Domanda

Ho chiesto href="https://stackoverflow.com/questions/966274/wpf-isenabled-binding-to-dependencyproperty-not-working-properly"> una domanda qui ma poi ho realizzato il mio problema non era il codice, ma lo stile che sto usando per un pulsante. Dal momento che il problema è completamente diverso da quello inizialmente chiesto, ho pensato che sarebbe stato più vantaggioso per gli altri utenti, se ho solo chiesto di nuovo la domanda "giusta". Qui vado:

Sto usando il modello sottostante nel mio pulsante. Quando ho creato button.IsEnabled = false funziona bene, ma se ho impostato button.IsEnabled = true non venga attivato. Potete per favore individuare ciò che sto facendo male? Grazie

<Style x:Key="BlackButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="MouseOverActivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF2F2F2F"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.1270000" Value="#FF2391FF"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="MouseOverDeactivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="rectangle">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF2391FF"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.2200000" Value="#FF2F2F2F"/>

                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="PressActivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF2391FF"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.1370000" Value="#FF48D6FF"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="PressedDeactivating" FillBehavior="Stop" >
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="rectangle">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF48D6FF"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.2370000" Value="#FF2391FF"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="DisableActivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FFA7A7A7"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                </ControlTemplate.Resources>
                <Grid>
                    <Rectangle Stroke="Transparent" RadiusX="5" RadiusY="5" x:Name="rectangle">
                        <Rectangle.Fill>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#FF000000" Offset="0"/>
                                <GradientStop Color="#FF2F2F2F" Offset="1"/>
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True" OpacityMask="{x:Null}"/>
                    <Rectangle Stroke="Transparent" RadiusX="5" RadiusY="5" x:Name="WhiteGlow">
                        <Rectangle.Fill>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#5BFFFFFF" Offset="0"/>
                                <GradientStop Color="#00FFFFFF" Offset="0.5"/>
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsCancel" Value="False"/>
                    <EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
                    <Trigger Property="IsFocused" Value="True">
                        <Trigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverActivating}" x:Name="MouseOverActivating_BeginStoryboard2"/>
                        </Trigger.ExitActions>
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverActivating}" x:Name="MouseOverActivating_BeginStoryboard1"/>
                        </Trigger.EnterActions>
                    </Trigger>
                    <Trigger Property="IsDefaulted" Value="True"/>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Trigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverDeactivating}" x:Name="MouseOverDeactivating_BeginStoryboard"/>
                        </Trigger.ExitActions>
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverActivating}" x:Name="MouseOverActivating_BeginStoryboard"/>
                        </Trigger.EnterActions>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard x:Name="PressActivating_BeginStoryboard" Storyboard="{StaticResource PressActivating}"/>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <BeginStoryboard x:Name="PressedDeactivating_BeginStoryboard" Storyboard="{StaticResource PressedDeactivating}"/>
                        </Trigger.ExitActions>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource DisableActivating}" x:Name="DisableActivating_BeginStoryboard"/>
                        </Trigger.EnterActions>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
È stato utile?

Soluzione

Ho il sospetto che il comportamento che state vedendo è il risultato dell'animazione che si utilizza quando IsEnabled diventa falsa. DependencyProperties realtà hanno una precedenza associate loro, in cui animazioni sono in alto nella lista; quella gerarchia, da MSDN , è:

  
      
  • sistema di proprietà coercizione
  •   
  • animazioni attivi, o animazioni con un comportamento di attesa.
  •   
  • Valore locale
  •   
  • proprietà del modello TemplatedParent
  •   
  • stile implicito
  •   
  • trigger stile
  •   
  • trigger modello
  •   
  • setter stile
  •   
  • default (tema) stile
  •   
  • Ereditato da padre
  •   
  • Il valore di default dai metadati proprietà di dipendenza
  •   

Per impostazione predefinita, le animazioni hanno una FillBehavior di HoldEnd, il che significa che rimangono al valore che l'animazione si è conclusa a. Quando IsEnabled diventa vero attraverso il vostro legame, che l'aggiornamento avviene a livello 'valore locale' in precedenza, e dal momento che lo storyboard DisableActivating sta tenendo l'aspetto a un livello superiore di precedenza ( 'animazioni con un comportamento Hold'), non si vede il cambiamento pulsante una volta ha cambiato la prima volta.

Ci sono tre soluzioni a questo:

  1. Aggiorna il tuo animazione per avere un FillBehavior di stop, il che significa che l'animazione non affermare il 'IsEnabled = False' visiva una volta l'animazione si ferma. Avrete bisogno di uno standard, grilletto non animata con lo stesso stato come la fine dell'animazione di continuare a far valere una volta completata l'animazione, altrimenti ti basta vederlo tornare indietro allo stato in cui era quando è iniziata l'animazione . Dal momento che è solo un insieme di trigger, quando il valore locale viene aggiornato lo vedrai tornare al valore originale come ci si aspetta. Inoltre, dal momento che l'animazione è di più alta priorità, è possibile impostare lo stile e avviare l'animazione contemporaneamente e solo "vedere" gli effetti dello stile, una volta completata l'animazione (in modo che il dissolvenza funzionerà come previsto).
  2. Invece di cambiare il FillBehavior, è possibile creare un nuovo trigger che si applica quando IsEnabled è vero che anima (forse istantaneamente) di nuovo allo stato originale. Questo può essere fatto anche mediante l'applicazione di un'animazione in ExitAction del trigger. Poiché è anche un'animazione ma è stato applicato in seguito, questo sostituirà lo stato HoldEnd dell'altro animazione. In un certo senso, questo è più facile che l'opzione 1, ma può diventare una seccatura per mantenere un attaccante e l'animazione indietro, soprattutto se non è necessario l'animazione inversa per uno specifico effetto visivo; si consiglia di tenerlo a svanire in e fuori lo stato disattivato, tuttavia.
  3. Aggiungi un ExitAction per il trigger IsEnabled per fermare la storyboard, impedendo l'animazione di continuare ad affermare il valore che aveva al termine dell'animazione in modo che lo stile valore locale può essere applicata. Questa opzione ha i vantaggi di non dover ripetere lo stile (come in # 1), mentre anche non avendo a invertire l'animazione (come in # 2).

Tra le tre soluzioni, l'ultima è probabilmente il punto di vista architettonico più pulito (a meno che abbiate un motivo specifico, come la necessità di svanire sia dentro che fuori, di preferire una delle altre opzioni - o una combinazione delle opzioni sopra).

Altri suggerimenti

L'opzione più semplice è quella di aggiungere un'animazione il grilletto ExitAction IsEnabled che tornerà l'animazione nella EnterAction

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top