开发者

Empty message on ItemsControl when binding List<T> is empty!

I am seeking for a way to show a message No records found instead of a the ItemsControl that is rending my List<T> when my list.Count == 0!

I did this once in WPF using DataTemplateSelector, but it seems that Silverlight doesn't support this!

It would be nice to have this UI logic in XAML instead of backend or my ViewModel which is comparati开发者_JS百科vely easy!

TIA

Delwar


You can bind the Visibility property of the ItemsControl to the source list using a custom IValueConverter; inside the IValueConverter you can return Visibility.Visible or Visibility.Collapsed according to the number of items into the source collection.
The same goes, with a converter using an opposite logic, for a TextBlock containing the "No items" message.

I can't figure how to solve the empty list problem with DataTemplateSelector, since the Empty template will not be applied anyway. Yet, you can achieve quite the same behaviour of DataTemplateSelector using an IValueConverter to bind the list to the DataTemplate property. Using this solution, however, makes difficult to return a DataTemplate defined in the control Xaml; you can use a template stored into applicatior resources, though.

Does it help?


I've come up with a simple solution for listboxes that works for me in 99% of the cases. Once setup as a resource, all you have to do is change the Tag property on the listbox to get all the functionality to work.

First, I modify the default template of the Listbox to include a new grid and a textbox like so:

Original XAML

<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3" Margin="0">
    <ScrollViewer x:Name="ScrollViewer" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Margin="0" Padding="0" TabNavigation="{TemplateBinding TabNavigation}">
        <ItemsPresenter Margin="0,0" />
    </ScrollViewer>
</Border>

New XAML

<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3" Margin="0">
    <Grid >
        <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tag}" VerticalAlignment="Center" HorizontalAlignment="Center" Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ItemsSource.Count, Converter={StaticResource ListCount2Visibility}}" Foreground="{StaticResource NormalFontBrush}" FontSize="{StaticResource DefaultFontSize}" />

        <ScrollViewer x:Name="ScrollViewer" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Margin="0" Padding="0" TabNavigation="{TemplateBinding TabNavigation}">
            <ItemsPresenter Margin="0,0" />
        </ScrollViewer>
    </Grid>
</Border>

The textblock visibility property is bound to a custom converter entitled ListCount2Visibility which looks like this:

public sealed class ListCount2Visibility : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null && (int)value > 0 )
            return "Collapsed";
        else
            return "Visible";

    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

The value converter checks if the ItemSource.Count == 0...if it is, it sets the visibility to visible. Otherwise, it collapses it.

The Text property of the new textblock is then bound to the Tag property of the listbox. (This isn't ideal but it is the quickest way to get the text into the control. Obviously this won't work if you use the tag property for other things).

So basically, you set the tag to the message you want to display, and anytime there are no items in the list, the textbox is shown (centered horizontally and vertically). During development, your message will show since the list is empty (assuming now design time datacontext) which makes it nice to visualize the text.

That is really all there is to it.

If you want, you can even bind the tag property of the listbox to your viewmodel to change the text. So you could do things like "loading...." while items are returned from the database and then change it to the "empty list" message after everything loads. (of course busy indicator is probably better)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜