Триггеры WPF влияют на значения, установленные в коде, а не в XAML.
Вопрос
В моем приложении есть кнопки-переключатели, которые имеют три возможных состояния;«Неотмечено», «Отмечено» и «Ранее использовано».Когда пользователь переходит на этот конкретный экран, некоторые кнопки переключения будут находиться в состоянии «Ранее использовано», чтобы показать, какая работа была проделана.Нажатие кнопки-переключателя (независимо от текущего состояния) переводит его в состояние «Проверено».Одновременно можно отметить только одну из этих кнопок-переключателей.Различные состояния обозначаются внешним свечением разного цвета или отсутствием свечения вообще.
Чтобы установить внешнее свечение для состояния «Проверено», я использую триггер IsChecked euqals true.
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Color="Salmon" BlurRadius="40" ShadowDepth="0" Opacity="1.0"></DropShadowEffect>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
Для состояния «Ранее использовано» я применяю внешнее свечение в коде, а не в разметке.Мне приходится это делать, потому что определение того, должна ли кнопка находиться в этом состоянии, осуществляется путем проверки значений в списке.
if (mExistingViews.Contains(mViews[i].LocalizedName))
{
DropShadowEffect dse = new DropShadowEffect();
dse.ShadowDepth = 0;
dse.BlurRadius = 20;
dse.Opacity = 1.0;
dse.Color = Colors.Yellow;
mViewButtons[i].Effect = dse;
}
Однако при нажатии кнопки переключения в состоянии «Ранее использовано» триггер, похоже, не оказывает никакого эффекта.Внешнее свечение не меняется.
Что я делаю не так?Не повлияет ли триггер на что-то, что не установлено в XAML?
Решение
Как только вы установите DropShadowEffect
на Button
, вы устанавливаете локальное значение Button
's Effect
имущество, которое представляет собой DependencyProperty
(Button.EffectProperty
).Локальное значение переопределяет любое другое возможное значение, пока оно не будет очищено следующим образом:
button1.ClearValue( Button.EffectProperty );
Однако это только делает работу немного более запутанной, потому что вам также необходимо убедиться, что вы очистили его, если он был установлен ранее и еще не был очищен.
Вместо этого вы можете создать AttachedProperty PreviouslyUsed
надеть ToggleButton
и использовать Bindings
поэтому они получают свою ценность более автоматически.Затем обратитесь к этому значению AttachedProperty в своих триггерах, и у вас будет одна тень для PreviouslyUsed
, и еще один для IsChecked
.
Часть, которую вам нужно будет подключить, — это привязка, и вам, вероятно, придется использовать IValueConverter
где-то повернуть mViews[i].LocalizedName
в true
или false
для PreviouslyUsed
.
К сожалению, я недостаточно знаю о вашей настройке с mViews
и тому подобное, чтобы дать больше советов по этому поводу.Я не знаю, твой ли ToggleButtons
являются частью привязки данных или нет.Я подозреваю, что это не так, поскольку вы, кажется, повторяете их массив.Если ты связал свой mViews
возражает против ItemsSource
из ListBox
, например, вы можете создать DataTemplate
который генерирует ToggleButtons
с уже имеющимся AttachedProperty.Это также упростит вашу IsChecked
ситуацию, привязав ее к тому, выбран ли этот элемент в ListBox
, а затем ListBox
заботится о том, чтобы был выбран только один.