2010-03-07 12 views
3

J'ai deux Etats visuels définis dans mon MainWindow Grid LayoutRoot comme suit:WPF - Manipuler VisualState d'un UserControl

<Grid x:Name="LayoutRoot" Background="#FF434343" ShowGridLines="True"> 

<Grid.RowDefinitions> 
    <RowDefinition Height="100"/> 
    <RowDefinition Height="*"/> 
</Grid.RowDefinitions> 


    <VisualStateManager.CustomVisualStateManager> 
     <ic:ExtendedVisualStateManager/> 
    </VisualStateManager.CustomVisualStateManager> 
    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup x:Name="VisualStateLogin"> 
      <VisualStateGroup.Transitions> 
       <VisualTransition GeneratedDuration="00:00:00.6000000"/> 
      </VisualStateGroup.Transitions> 
      <VisualState x:Name="LoggedOn"> 
       <Storyboard> 
        <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="{x:Null}" Storyboard.TargetProperty="(Window.WindowStyle)"> 
         <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static WindowStyle.None}"/> 
        </ObjectAnimationUsingKeyFrames> 
        <BooleanAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="{x:Null}" Storyboard.TargetProperty="(Window.AllowsTransparency)"> 
         <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="True"/> 
        </BooleanAnimationUsingKeyFrames> 
       </Storyboard> 
      </VisualState> 
      <VisualState x:Name="LoggedOff"> 
       <Storyboard> 
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="brdContent" Storyboard.TargetProperty="(UIElement.Opacity)"> 
         <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.1"/> 
        </DoubleAnimationUsingKeyFrames> 
        <BooleanAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="brdContent" Storyboard.TargetProperty="(UIElement.IsEnabled)"> 
         <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False"/> 
        </BooleanAnimationUsingKeyFrames> 
        <BooleanAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="ucTabButtons" Storyboard.TargetProperty="(UIElement.IsEnabled)"> 
         <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False"/> 
        </BooleanAnimationUsingKeyFrames> 
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="ucTabButtons" Storyboard.TargetProperty="(UIElement.Opacity)"> 
         <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.4"/> 
        </DoubleAnimationUsingKeyFrames> 
       </Storyboard> 
      </VisualState> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 

Il fonctionne très bien passage d'un état à un autre thoughtout le codebehind MainWindow, comme ça:

void MainWindow_Loaded(object sender, RoutedEventArgs e) 
    { 
     //ExtendedVisualStateManager.GoToElementState(this.LayoutRoot as FrameworkElement, "LoggedOff", false);   
    } 

Mais maintenant, je dois être en mesure de les états de commutation d'un usercontrol à l'intérieur du MainWindow ...

Je tryed que:

private void btnOk_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     MainWindow parent = new MainWindow(); 
     Grid root = new Grid(); 
     root = (Grid)parent.FindName("LayoutRoot"); 
     ExtendedVisualStateManager.GoToElementState(root as FrameworkElement, "LoggedOn", true); 
    } 

Et il me donne l'exception suivante:

System.NullReferenceException a été unhandled message = "référence d'objet non définie à une instance d'un objet." Source = "WPFToolkit"

Est-ce que quelqu'un sait comment changer d'état à partir d'un usercontrol?

ThankYou,

Josi

Répondre

1

je recommande de définir une interface de commutation entre états. Le formulaire peut implémenter l'interface et il peut passer explicitement l'interface au contrôle ou le contrôle peut interroger son parent pour voir si l'interface est implémentée. De cette façon, le contrôle de l'utilisateur n'est pas étroitement lié à son conteneur, uniquement au comportement attendu par le conteneur. Sur une note de côté, avoir un contrôle utilisateur modifier l'état de son conteneur est une conception inhabituelle. Vous voudrez peut-être envisager s'il existe un autre moyen de structurer l'exigence.

Une interface possible:

public interface IStateChanger 
{ 
    void GoToElementState(string state);  
} 

Vous pouvez avoir votre MainWindow implémenter cette interface:

void IStateChanger.GoToElementState(string state) 
    { 
     ExtendedVisualStateManager.GoToElementState(this.LayoutRoot as FrameworkElement, state, false);   
    } 

Ensuite, votre commande, votre exemple, peut faire:

private void btnOk_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     MainWindow parent = new MainWindow(); 
     if (parent is IStateChanger) 
      ((IStateChanger)parent).GoToElementState("LoggedOn"); 
    } 
0

Créez un événement public sur votre contrôle utilisateur auquel le parent peut s'abonner; l'événement peut alors être utilisé comme déclencheur pour la transition d'état.