2010-08-19 22 views
1

Je suis actuellement confronté à un scénario que je ne sais pas quelle est la meilleure façon de gérer.Meilleure façon de propager VisualState changements

Scénario:

  1. ControlA a 2 deux visualstates personnalisés, nous allons les appeler « StateOn » et « StateOff ».
  2. J'applique maintenant un template sur ControlA, appelons-le "templateA". "TemplateA" a un contrôle en dessous de type ControlB (qui ne connaît pas StateOn/Off)
  3. ControlB possède un modèle qui gère les changements d'état visuel de ControlA, à savoir StateOn et StateOff.

Problème:
ControlB ne reçoit pas des modifications aux VisualStates ont tiré sur ControlA, donc pas de changements visuels se produisent.

Je pense que le problème a à voir avec l'élément racine étant un contrôle (ControlB), qui ne déclenche pas gotostate sur les états souhaités. Cependant, je me demande quelle est la manière la plus simple/la plus propre de propager les changements de controlatest de ControlA à ControlB.

Merci pour votre aide!

Henry

Xaml: -

<UserControl x:Class="VisualStateChangePropagation.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:VisualStateChangePropagation" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot" Background="White"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="20"/> 
      <ColumnDefinition Width="50"/> 
      <ColumnDefinition Width="20"/> 
     </Grid.ColumnDefinitions> 
     <Grid.Resources> 

      <SolidColorBrush x:Name="Fill_Bg_Red" Color="Red"/> 
      <SolidColorBrush x:Name="Fill_Bg_Blue" Color="Blue"/> 

      <ControlTemplate x:Name="templateA" TargetType="Control"> 
       <Grid> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="Common"> 
          <VisualState x:Name="StateOn"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="m_rect" 
                    Storyboard.TargetProperty="(Rectangle.Fill)"> 
             <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Fill_Bg_Red}" /> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="StateOff"/> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Rectangle x:Name="m_rect" Fill="{StaticResource Fill_Bg_Blue}"/> 
       </Grid> 
      </ControlTemplate> 

      <ControlTemplate x:Name="templateB" TargetType="Control"> 
       <local:ControlB Template="{StaticResource templateA}"/> 
      </ControlTemplate> 

     </Grid.Resources> 
     <local:ControlA x:Name="m_control1" Template="{StaticResource templateA}" Grid.Column="0"/> 
     <Button Click="Button_Click" Grid.Column="1" Content="swap"/> 
     <local:ControlA x:Name="m_control2" Template="{StaticResource templateB}" Grid.Column="2"/> 
    </Grid> 
</UserControl> 
Code

derrière:

public class ControlA : Control 
{ 
    public void ToggleState() 
    { 
     m_isSet = !m_isSet; 
     UpdateVisualState(); 
    } 

    private void UpdateVisualState() 
    { 
     string targetState = m_isSet ? "StateOn" : "StateOff"; 
     VisualStateManager.GoToState(this, targetState, false); 
    } 

    private bool m_isSet = false; 
} 

public class ControlB : Control 
{ 

} 
+0

Bienvenue à SO, veuillez prendre quelques minutes pour lire la FAQ et la documentation de Markdown (un synopsis utile est disponible dans la marge de droite lors de l'édition d'une question). – AnthonyWJones

Répondre

0

d'abord à la fois ControlA et ControlB devrait avoir une propriété de dépendance pour IsSet. Contrairement à votre intuition, les états visuels ne se propagent pas du tout. Les états ne sont significatifs que pour le contrôle auquel ils sont directement rattachés. Cependant, avec cette propriété de dépendance ajoutée aux deux commandes que vous pouvez propager la valeur de la propriété par modèle de liaison: -

 <ControlTemplate x:Name="templateB" TargetType="Control"> 
      <local:ControlB Template="{StaticResource templateA}" IsSet="{TemplateBinding IsSet}" /> 
     </ControlTemplate> 

En ce qui concerne votre code de ControlA d'origine le champ m_isSet n'est plus nécessaire: -

public void ToggleState() 
{ 
    IsSet = !IsSet; 
}