Триггеры WPF влияют на значения, установленные в коде, а не на XAML - PullRequest
0 голосов
/ 07 августа 2009

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

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

1 Ответ

2 голосов
/ 07 августа 2009

После установки DropShadowEffect на Button вы устанавливаете локальное значение свойства Button s Effect, которое является DependencyProperty (Button.EffectProperty). Локальное значение переопределяет любое другое возможное значение, пока оно не будет очищено следующим образом:

button1.ClearValue( Button.EffectProperty );

Однако, это только делает работу немного более запутанной, потому что вы также должны убедиться, что вы очистили ее, если она была установлена ​​ранее и еще не очищена.

Вместо этого вы могли бы создать AttachedProperty PreviouslyUsed, чтобы надеть ToggleButton s и использовать Bindings, чтобы они получали свое значение немного более автоматически. Затем обратитесь к этому значению AttachedProperty в ваших триггерах, и у вас будет одна тень для PreviouslyUsed, а другая для IsChecked.

Часть, которую вам нужно подключить, - это привязка, и вам, вероятно, придется использовать IValueConverter где-нибудь, чтобы превратить mViews[i].LocalizedName в true или false для PreviouslyUsed.

К сожалению, я недостаточно знаю о вашей настройке с mViews и тому подобное, чтобы дать больше советов по этому поводу. Я не знаю, являются ли ваши ToggleButtons частью привязки данных или нет. Я подозреваю, что это не так, как вы, кажется, итерируете их массив. Например, если вы связали свои mViews объекты с ItemsSource из ListBox, вы можете создать DataTemplate, который генерирует ToggleButtons с уже установленным AttachedProperty. Это также упростит вашу ситуацию IsChecked, связав ее с тем, выбран ли этот элемент в ListBox, а затем ListBox позаботится о том, чтобы был выбран только один.

...