我在MainWindow的LayoutRoot Grid中定义了两个可视状态,如下所示:
<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>
它可以很好地从一个状态切换到另一个状态,从而考虑到MainWindow代码隐藏,就像那样:
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//ExtendedVisualStateManager.GoToElementState(this.LayoutRoot as FrameworkElement, "LoggedOff", false);
}
但是现在,我需要能够从MainWindow中的用户控件切换状态......
我试过了:
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);
}
它给了我以下例外:
System.NullReferenceException未处理 Message =“对象引用未设置为对象的实例。” 源= “WPFToolkit”
有人知道如何从用户控件切换状态吗?
THANKYOU,
Josi
答案 0 :(得分:1)
我建议定义一个用于在状态之间切换的界面。表单可以实现接口,它可以显式地将接口传递给控件,或者控件可以查询其父接口以查看接口是否已实现。这样,用户控件就不会与其容器紧密耦合,只与其期望容器提供的行为相关联。
另一方面,让用户控件修改其容器的状态是一种不寻常的设计。您可能想要考虑是否有另一种方法来构建需求。
可能的界面:
public interface IStateChanger
{
void GoToElementState(string state);
}
您可以让MainWindow实现此界面:
void IStateChanger.GoToElementState(string state)
{
ExtendedVisualStateManager.GoToElementState(this.LayoutRoot as FrameworkElement, state, false);
}
然后你的控制,按照你的例子,可以做到这一点:
private void btnOk_Click(object sender, System.Windows.RoutedEventArgs e)
{
MainWindow parent = new MainWindow();
if (parent is IStateChanger)
((IStateChanger)parent).GoToElementState("LoggedOn");
}
答案 1 :(得分:0)
在您的用户控件上创建父级可以订阅的公共事件;然后,该事件可以用作状态转换的触发器。