Триггеры WPF влияют на значения, установленные в коде, а не в XAML.

StackOverflow https://stackoverflow.com/questions/1241591

  •  12-09-2019
  •  | 
  •  

Вопрос

В моем приложении есть кнопки-переключатели, которые имеют три возможных состояния;«Неотмечено», «Отмечено» и «Ранее использовано».Когда пользователь переходит на этот конкретный экран, некоторые кнопки переключения будут находиться в состоянии «Ранее использовано», чтобы показать, какая работа была проделана.Нажатие кнопки-переключателя (независимо от текущего состояния) переводит его в состояние «Проверено».Одновременно можно отметить только одну из этих кнопок-переключателей.Различные состояния обозначаются внешним свечением разного цвета или отсутствием свечения вообще.

Чтобы установить внешнее свечение для состояния «Проверено», я использую триггер 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 заботится о том, чтобы был выбран только один.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top