DataTrigger внутри ItemTemplate-DataTemplate не срабатывает при изменении свойства - PullRequest
0 голосов
/ 05 октября 2018

Я довольно новичок в WPF и сейчас пытаюсь выяснить, как добавить стилизованные шаблоны данных в элемент управления, в данном случае ListBox.

Я пытаюсь создать браузер элементов сListBox и выделите ListBoxItem с помощью пользовательского цвета при щелчке по нему, используя цветной прямоугольник на заднем плане.

ListBox связан с набором ObservableCollection с несколькими свойствами, включая свойство IsOpened.

<ListBox x:Name="MainPage_Entries" Height="643" Canvas.Left="10" Canvas.Top="10" Width="230">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="White" BorderThickness="1">
                <WrapPanel Margin="-2,0,0,0" HorizontalAlignment="Stretch">
                    <Grid HorizontalAlignment="Stretch">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="30"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Rectangle Margin="0" HorizontalAlignment="Stretch" Height="40" Grid.ColumnSpan="2">
                            <Rectangle.Style>
                                <Style TargetType="Rectangle">
                                    <Setter Property="Fill" Value="Gray"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsOpened}" Value="True">
                                            <Setter Property="Fill" Value="Black"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Rectangle.Style>
                        </Rectangle>

                        <Image Source="{Binding SourceImage}" Height="30"/>
                        <TextBlock Margin="3,1,3,0" Text="{Binding SetName}" Grid.Column="1" VerticalAlignment="Top" Width="188" FontFamily="Arial" FontSize="16" Foreground="White"/>
                        <TextBlock Margin="3,0,3,5" Text="{Binding OutputName}" Grid.Column="1" VerticalAlignment="Bottom" Width="188" Foreground="White" FontSize="10" FontStyle="Italic"/>
                    </Grid>
                </WrapPanel>
            </Border>


        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBoxItem_ClickDown"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

При щелчке по элементу ListBoxItem свойство IsOpened выбранного элемента устанавливается в значение False, а для выбранного - значение True.Даже если изменение свойства успешно выполняется в ObservableCollection, триггер остается нетронутым, а фон остается черным (инициализированное значение IsOpened - True).

EDIT:

DataTriggerДо сих пор это изменилось:

<DataTrigger Binding="{Binding Path=IsOpened, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" Value="True">
    <Setter Property="Fill" Value="Black"/>
</DataTrigger>

И текущее состояние класса записи:

public class EntryItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void NotifyPropertyChanged([CallerMemberName]string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public string SetName { get; set; }

    public string SourceImage { get; set; }

    public EntryItem(string name)
    {
        SetName = name;
        IsOpened = true;
    }

    private bool _isOpened;
    public bool IsOpened
    {
        get { return _isOpened; }
        set {
            _isOpened = value;
            NotifyPropertyChanged();
        }
    }
}

При добавлении этих данных фон всех записей остается серым, даже если один«IsOpened».

РЕДАКТИРОВАТЬ 2:

Удаление бита RelativeSource заставило его работать. Заключение : Реализация INotifyPropertyChanged.

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Класс, в котором определено свойство IsOpened, должен реализовывать интерфейс INotifyPropertyChanged и вызывать событие PropertyChanged, когда установлено свойство IsOpened:

class DataObject : INotifyPropertyChanged
{
    private bool _isOpened;
    public bool IsOpened
    {
        get { return _isOpened; }
        set { _isOpened = value; NotifyPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
0 голосов
/ 05 октября 2018

Если вы уверены, что этот список имеет тот же DataContext, что и свойство IsOpened, существует, я попытался бы разрешить его, настроив RelativeSource для самого списка:

<Rectangle Margin="0" HorizontalAlignment="Stretch" Height="40" Grid.ColumnSpan="2">
    <Rectangle.Style>
        <Style TargetType="Rectangle">
            <Setter Property="Fill" Value="Gray"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsOpened, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" Value="True">
                    <Setter Property="Fill" Value="Black"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Rectangle.Style>
</Rectangle>
...