WPF desencadenantes que afectan a los valores establecidos en el código, no XAML
Pregunta
En mi aplicación tengo botones de conmutación que tienen tres estados posibles; "Sin control", "cuadros", y "empleado hasta el momento". Cuando el usuario llega a esta pantalla en particular, algunos de los botones de selección estará en el estado "empleado hasta el momento" para mostrar lo que el trabajo se ha hecho. Al hacer clic en un botón de activación (no importa el estado actual) lo colocará en el estado "marcado". Sólo uno de estos botones de conmutación se puede comprobar a la vez. Los diferentes estados se indican mediante diferentes resplandor exterior coloreado, o no resplandor en absoluto.
Para establecer el brillo exterior para el estado "marcado" utilizo un disparador en IsChecked euqals cierto.
<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>
En el estado "empleado hasta el momento" aplico el brillo exterior en el código, no de marcado. Tengo que hacer esto porque la determinación de si el botón debe estar en este estado se hace mediante la comprobación de valores de una lista.
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;
}
Sin embargo, cuando se hace clic en un botón de activación cuando está en estado "empleado hasta el momento", no parece el gatillo para tener algún efecto. El resplandor exterior no cambia.
¿Qué estoy haciendo mal? Será un disparador no efectuar algo que no se ha establecido en XAML?
Solución
Una vez que se establece la DropShadowEffect
en el Button
, se está ajustando el valor local de la propiedad Button
del Effect
, que es un DependencyProperty
(Button.EffectProperty
). El valor local prevalece sobre cualquier otro valor posible hasta que se aclare este aspecto:
button1.ClearValue( Button.EffectProperty );
Sin embargo, eso sólo hace que el funcionamiento de un poco más complicado, ya que también tiene que asegurarse de que se borre si se estableció antes y no ha sido aprobado todavía.
En su lugar, se podría crear un PreviouslyUsed
AttachedProperty para poner en las ToggleButton
s y utilizar Bindings
por lo que obtener su valor un poco más automágicamente. A continuación, se refieren a este valor AttachedProperty en sus desencadenantes y vas a tener una gota de sombra de PreviouslyUsed
, y otro para IsChecked
.
La parte que tendrá que cablear es la unión, y es probable que tenga que utilizar un IValueConverter
donde acudir mViews[i].LocalizedName
en un true
o false
para PreviouslyUsed
.
Por desgracia, no sé lo suficiente sobre su configuración con mViews
y tal para ofrecer más consejos sobre eso. No sé si su ToggleButtons
forman parte del enlace de datos o no. Sospecho que no lo son, como usted parece ser la iteración de una gran variedad de ellos. Si usted limita sus objetos mViews
a la ItemsSource
de un ListBox
, por ejemplo, se podría crear una DataTemplate
que genera el ToggleButtons
con el AttachedProperty ya en su lugar. Eso también simplificar su situación IsChecked
enlazándolo a si o no ese elemento se selecciona en el ListBox
, y luego el ListBox
se encarga de asegurarse de que sólo se selecciona uno.