Управление стилем на основе DependencyProperty

Итак, я создаю приложение WPF, используя шаблон проектирования MV-VM, и у меня возникают проблемы с правильной работой моих привязок.

У меня есть собственный ToggleButton, и я хочу, чтобы он работал так:

  1. Когда для свойства IsChecked элемента управления установлено значение true, тогда он должен запрашивать второе логическое значение (содержащееся в ViewModel), которое также имеет значение true.
  2. Если это так, установите цвет фона на один цвет, если нет, установите его на другой цвет.
  3. Если IsChecked имеет значение false, используйте стандартный цвет.

В xaml у меня есть этот стиль:

<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource CustomisableToggleButton}" x:Key="ValidatedTButton">
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsChecked}" Value="True" />
                <Condition Binding="{Binding IsValid}" Value="True" />
            </MultiDataTrigger.Conditions>
            <MultiDataTrigger.Setters>
                <Setter Property="Background" Value="Turquoise" />
            </MultiDataTrigger.Setters>
        </MultiDataTrigger>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsChecked}" Value="True" />
                <Condition Binding="{Binding IsValid}" Value="False" />
            </MultiDataTrigger.Conditions>
            <MultiDataTrigger.Setters>
                <Setter Property="Background" Value="LightCoral" />
            </MultiDataTrigger.Setters>
        </MultiDataTrigger>
        <DataTrigger Binding="{Binding IsChecked}" Value="False">
            <Setter Property="Background" Value="AliceBlue" />
        </DataTrigger>
    </Style.Triggers>
</Style>

(CustomisableToggleButton - это универсальный стиль, который применяется к ToggleButtons - AFAIK, это должно переопределять присущие ему триггеры - поправьте меня, если я ошибаюсь)

В классе управления:

public class ValidatedToggleButton : ToggleButton
{
    public ValidatedToggleButton()
        : base() { }

    public static readonly DependencyProperty IsValidProperty = DependencyProperty.Register(
        "IsValid", typeof(bool), typeof(ValidatedToggleButton));

    public bool IsValid
    {
        get { return (bool)GetValue(IsValidProperty); }
        set { SetValue(IsValidProperty, value); }
    }
}

И фактическая реализация элемента управления:

<Window
<!--standard window properties-->
    xmlns:cc="clr-namespace:MVVM.CustomControls"> // namespace where 'ValidatedToggleButton' resides

<!--other XAML code-->

    <cc:ValidatedToggleButton 
        IsValid="{Binding Boolean1}" 
        Content="ToggleButton1" 
        IsChecked="{Binding ToggleButton1Checked}" 
        Grid.Row="6" Style="{StaticResource ValidatedTButton}" />

</Window>

Теперь проблема в том, что он никогда не проверяет значение «Boolean1», кроме одного раза при запуске (проверено с помощью точек останова). Как я могу заставить его проверять это значение каждый раз, когда нажимается элемент управления?


person Kristian Fenn    schedule 20.10.2011    source источник


Ответы (2)


В дополнение к ответу Кента об исправлении привязок XAML , убедитесь, что событие PropertyChanged вызывается при изменении Boolean1.

Вы можете сделать это, вставив точку останова в метод get.

person Rachel    schedule 20.10.2011

<Condition Binding="{Binding IsChecked}" Value="True" />

Это ищет свойство с именем IsChecked в вашей модели представления (ваш контекст данных). Вы уверены, что не хотите этого:

<Condition Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="True" />
person Kent Boogaart    schedule 20.10.2011
comment
Я пропустил это, но, к сожалению, не сигару. В любом случае, «IsChecked», кажется, работает нормально, проблемы вызывает только «IsValid». - person Kristian Fenn; 20.10.2011
comment
Взяв этот ответ и применив его к «IsValid», мы получили интересный результат — теперь ToggleButton всегда отображается как недопустимый цвет, а не как допустимый… странно. - person Kristian Fenn; 20.10.2011
comment
@KristianFenn Сделайте то же самое со свойством IsValid. Прямо сейчас похоже, что вы проверяете значение ValidatingToggleButton.DataContext.IsValid, которого, как я предполагаю, не существует. Установив RelativeSource на Self, вы измените его, чтобы посмотреть на ValidatingToggleButton.IsValid - person Rachel; 20.10.2011
comment
@KristianFenn Извините, я этого не видел. Вы убедились, что свойство Boolean1 в вашем DataContext получает значение true и вызывает событие PropertyChanged? - person Rachel; 20.10.2011
comment
@Rachel Свойство «Boolean1» не следует обычному общедоступному свойству для предоставления шаблона частного члена — оно возвращает результат сравнения. В результате в свойстве нет части set{}, так как нет закрытого члена для установки. - person Kristian Fenn; 20.10.2011
comment
Добавлены события NotifyPropertyChanged() везде, где изменяются параметры сравнения «Boolean1». Еще нет сигары. - person Kristian Fenn; 20.10.2011
comment
@KristianFenn Можете ли вы установить точку останова в методе get для Boolean1 и убедиться, что он вызывается, когда вы вручную вызываете события PropertyChanged? - person Rachel; 20.10.2011
comment
@Rachel Это может показаться проблемой при сравнении. Однако некоторые вызовы NotifyPropertyChanged() отсутствовали, что решает проблему, когда «Boolean1» никогда не проверяется после инициализации. Я бы принял ваш ответ, но, к сожалению, это комментарий. - person Kristian Fenn; 20.10.2011
comment
@KristianFenn Я опубликовал это как ответ, но все же рекомендую дать Кенту +1 за публикацию решения вашего первоначального вопроса :) - person Rachel; 20.10.2011