INotifyPropertyChange игнорируется при привязке к DataTrigger

Я работаю над некоторым кодом, который имеет кнопку, содержащую изображение и некоторый текст, и который должен отображать либо изображение, либо текст, либо и то, и другое, в зависимости от значения связанного свойства. Код в настоящее время использует стили и DataTriggers:

public enum ButtonStyle { Image, Text, Both };

public class ViewModel : INotifyPropertyChanged
{
    private ButtonStyle _buttonStyle;
    public ButtonStyle buttonStyle
    {
        get { return this._buttonStyle; }
        set
        {
            this._buttonStyle = value;
            notifyPropertyChanged("buttonStyle");
        }
}

А также:

<UserControl.Resources>
    <Style x:Key="buttonTextStyle" TargetType="{x:Type Label}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=buttonStyle}"
                    Value="{x:Static local:ButtonStyle.Text}">
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="buttonImageStyle" TargetType="{x:Type Image}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=buttonStyle}"
                    Value="{x:Static local:ButtonStyle.Image}">
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>


<Button>
    <StackPanel>
        <Image Source="..." Style="{StaticResource buttonImageStyle} />
        <Label Style={StaticResource buttonTextStyle}>My Text</Label>
    </StackPanel>
</Button>

Моя проблема? Кнопка не меняется, когда я изменяю значение свойства buttonStyle в модели представления. Этот элемент управления находится на вкладке, и если я переключусь на другую вкладку, а затем переключусь обратно, кнопка обновится, чтобы отразить текущее значение свойства buttonStyle, но оно не изменится, пока я этого не сделаю.

Похоже, что DataTrigger обрабатывается только при визуализации элемента управления и не выполняет повторную визуализацию при изменении связанного значения, несмотря на то, что связанное значение вызывает событие PropertyChanged.

Есть идеи?


person Jeff Dege    schedule 18.10.2012    source источник


Ответы (3)


Попробуйте NotifyOnSourceUpdated=True для каждого из ваших триггеров данных.

        <DataTrigger Binding="{Binding Path=buttonStyle, NotifyOnSourceUpdated=True}"
                Value="{x:Static local:ButtonStyle.Text}">
            <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
person Kulvir    schedule 18.10.2012
comment
Пробовал. Это не имело никакого значения. - person Jeff Dege; 19.10.2012

Я думаю, что это лучший способ ссылаться на перечисления в вашем DataTrigger:

    <Style x:Key="buttonImageStyle" TargetType="{x:Type Image}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=buttonStyle}">
                <DataTrigger.Value>
                    <local:ButtonStyle>Text</local:ButtonStyle>
                </DataTrigger.Value>
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

Значение ресурса изменяется во время выполнения, поэтому вы должны использовать DynamicResource вместо StaticResource:

Style="{DynamicResource buttonImageStyle}"
person Florian Gl    schedule 19.10.2012
comment
Разница в выражении перечислений - это синтаксический сахар, любая форма эквивалентна. Что касается использования {DynamicResource=}... У меня были надежды на это, но это не сработало. - person Jeff Dege; 19.10.2012

Вот идея: каждый раз, когда у вас возникает проблема с привязкой, и кажется, что INotifyPropertyChanged не работает, проверьте и перепроверьте и убедитесь, что вы правильно написали имя свойства в своем PropertyChangedEventArgs().

Извините за беспокойство.

person Jeff Dege    schedule 19.10.2012
comment
:D Сработало с Style="{DynamicResource buttonImageStyle}"? - person Florian Gl; 19.10.2012
comment
Со StaticResource отлично работало, как только я начал уведомлять с правильным именем свойства. - person Jeff Dege; 20.10.2012
comment
Хорошо, тогда я действительно не понимаю разницы между StaticResource и DynamicResource... - person Florian Gl; 20.10.2012