Я предложил простое решение для списков, которое работает для меня в 99% случаев. После настройки в качестве ресурса все, что вам нужно сделать, это изменить свойство Tag в списке, чтобы заставить работать все функции.
Во-первых, я изменяю шаблон списка по умолчанию, чтобы включить новую сетку и текстовое поле следующим образом:
Оригинал 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>
Новый 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>
Свойство видимости textblock привязано к пользовательскому конвертеру с именем ListCount2Visibility, который выглядит следующим образом:
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();
}
}
Преобразователь значений проверяет, если ItemSource.Count == 0 ... если это так, он устанавливает видимость видимым. В противном случае он рухнет.
Свойство Text нового текстового блока затем связывается со свойством Tag списка. (Это не идеально, но это самый быстрый способ получить текст в элемент управления. Очевидно, что это не сработает, если вы используете свойство tag для других целей).
Таким образом, в основном вы устанавливаете тег для сообщения, которое хотите отобразить, и в любое время, когда в списке нет элементов, отображается текстовое поле (по центру по горизонтали и вертикали). Во время разработки ваше сообщение будет отображаться, поскольку список пуст (если предположить, что теперь время разработки datacontext), что позволяет визуализировать текст.
Это действительно все, что нужно.
Если вы хотите, вы можете даже привязать свойство тега списка к вашей модели представления, чтобы изменить текст. Таким образом, вы можете делать такие вещи, как «загрузка ...», пока элементы возвращаются из базы данных, а затем менять их на сообщение «пустой список» после того, как все загрузится. (конечно, индикатор занятости, вероятно, лучше)