MVVM WPF смена DataTemplate если список пуст

352
26 мая 2017, 11:09

есть ListBox

<ListBox x:Name="autoList" Grid.Column="0" ItemsSource="{Binding Auto}"  
             SelectedItem="{Binding SelectedAuto}">

в нем из базы загружаются автомобили. как сделать чтобы если база пуста(удалены все элементы или еще не заполнялась) ListBox заменялся на это

<TextBlock Text="Список пуст. Введите данные" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
Answer 1

Можно сделать с помощью DataTrigger без дополнительных свойств и конверторов:

<Grid> 
    <ListBox ItemsSource="{Binding Auto}"/>
    <Label Content="Список пуст">
        <Label.Style>
            <Style TargetType="Label">
                <Setter Property="Visibility" Value="Collapsed"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Auto.Count}" Value="0">
                        <Setter Property="Visibility" Value="Visible"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Label.Style>
    </Label>        
</Grid>

ListBox и Label должны находится в одном Grid(или хотя бы в одной ячейке) чтобы происходило наложение друг на друга.

Answer 2

Сначала напишем конвертер, который является отражением BooleanToVisibilityConverter:

public class InverseBooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? Visibility.Collapsed : Visibility.Visible;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

После этого дополним модель представления признаком наличия автомобилей:

class ViewModel
{
    ...
    public bool HasAuto
    {
        get { return Auto.Any(); }
    }
}

После этого добавим обработку видимости в представление:

<StackPanel>
    <StackPanel.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        <local:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
    </StackPanel.Resources>
    <ListBox Visibility="{Binding HasAuto, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}" 
             ItemsSource="{Binding Auto}" SelectedItem="{Binding SelectedAuto}" />
    <TextBlock Text="Список пуст. Введите данные" Visibility="{Binding HasAuto, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource InverseBooleanToVisibilityConverter}}" />
</StackPanel>

Остается только вовремя обновлять свойство HasAuto путем вызова PropertyChanged. Это можно сделать подписавшись на событие изменения коллекции Auto. Или можно вызывать событие PropertyChanged при загрузке, добавлении и удалении элементов из коллекции. Тогда подписка на событие изменения состава коллекции не понадобится.

UPD

Ну или можно воспользоваться триггерами (свойство HasAuto все равно понадобится)

<ContentPresenter Content="{Binding}">
    <ContentPresenter.Resources>
        <DataTemplate x:Key="AutoListTemplate">
            <ListBox ItemsSource="{Binding Auto}" SelectedItem="{Binding SelectedAuto}" />
        </DataTemplate>
        <DataTemplate x:Key="EmptyAutoListTemplate">
            <TextBlock Text="Список пуст. Введите данные" />
        </DataTemplate>
    </ContentPresenter.Resources>
    <ContentPresenter.Style>
        <Style TargetType="ContentPresenter">
            <Style.Triggers>
                <DataTrigger Binding="{Binding HasAuto, UpdateSourceTrigger=PropertyChanged}" Value="False">
                    <Setter Property="ContentTemplate" Value="{StaticResource EmptyAutoListTemplate}"/>
                </DataTrigger>
            </Style.Triggers>
            <Setter Property="ContentTemplate" Value="{StaticResource AutoListTemplate}" />
        </Style>
    </ContentPresenter.Style>
</ContentPresenter>
Answer 3

1. Объявите:

public ObservableCollection<string> Auto

2. В разметке:

<TextBlock Text="{Binding Auto.Count}">
    <TextBlock.Style>
        <Style TargetType="TextBlock">
            <Setter Property="Visibility" Value="Visible"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Auto.Count}" Value="0">
                    <Setter Property="Visibility" Value="Hidden"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

3. Аналогично Auto (только поменять Hidden/Visible)

READ ALSO
Проверка данных при импорте из Excel

Проверка данных при импорте из Excel

Есть таблица Excel содержащая в первом столбец название (условно Марка автомобиля), во втором столбце Модель автомобиляВ первом столбце названия...

279
SecureString хешировать MD5

SecureString хешировать MD5

Есть метод который принимает пароль и возвращает его уже захешированным в MD5Поначалу я использовал не SecureString а просто string в которую записывал...

393
как создать запрос where с двумя условиями?

как создать запрос where с двумя условиями?

есть 3 столба: 1-id 2-валюта, 3-значениекак сделать запрос, чтобы из таблицы вытащить сразу данные

349
Как вывести данные из базы данных?

Как вывести данные из базы данных?

Никак не получается вывести текст из базы данных на страницу, сижу уже часов 6 не получаетсяС подключением БД все нормально

438