xamlwindows-phone-8longlistselector

LongListSelector empty style


I want to show a TextBlock when the LongListSelector has no items. I can do it to every list in my app but that is not sane. So I am trying to edit the list style and do it to every list.

How can I bind to the LongListSelector ItemsSouce count inside its style?

Here is where I am now.

<Style TargetType="phone:LongListSelector">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="phone:LongListSelector">
                <Grid Background="{TemplateBinding Background}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="ScrollStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="00:00:00.5" />
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="Scrolling">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalScrollBar" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="NotScrolling" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Grid Margin="{TemplateBinding Padding}">
                        <i:Interaction.Triggers>
                            <!-- HERE I CANT BIND TO COUNT -->
                            <ec:DataTrigger Binding="{TemplateBinding ItemsSource}" Comparison="Equal" Value="0">
                                <ec:ChangePropertyAction TargetObject="{Binding ElementName=EmptyListText}" PropertyName="Visibility" Value="Visible" />
                            </ec:DataTrigger>
                        </i:Interaction.Triggers>
                        <ViewportControl x:Name="ViewportControl" HorizontalContentAlignment="Stretch" VerticalAlignment="Top" />
                        <ScrollBar x:Name="VerticalScrollBar" Opacity="0" Background="{StaticResource ThemeBackground}" HorizontalAlignment="Right" Orientation="Vertical" />
                        <TextBlock x:Name="EmptyListText" Visibility="Collapsed" Text="{Binding Source={StaticResource Literals}, Path=Literals.noResults}" />
                    </Grid>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Solution

  • It's a DataBinding issue.

    Try attaching it to the TemplateParent (which is the LongListSelector) like so:

    <ec:DataTrigger
        Binding="{Binding RelativeSource={RelativeSource Mode=TemplateParent}, Path=ItemsSource.Count}"
        Comparison="Equal" Value="0">
    </ec:DataTrigger>
    

    That should set you straight if you want to use your triggers.


    I like using Converters. It is a little simpler to understand so here's the full solution using a Converter.

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Windows.Data;
    
    public class MyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return Visibility.Collapsed;
            else
            {
                if (value is System.Collections.IList)
                {
                    System.Collections.IList list = (System.Collections.IList)value;
                    if (list.Count == 0)
                        return Visibility.Collapsed;
                    else
                        return Visibility.Visible;
    
                }
                else
                    return Visibility.Collapsed;                
            }
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }
    }
    

    So the LongListSelector Style is:

    <TextBlock Visibility="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource MyConverter}}"></TextBlock>