在使用Expression Blend为WPF开发UserControl时,我遇到了类似的问题(注意:如果您正在开发自定义控件,请参见我的下一节)。在那个UserControl中,我有一个子元素,希望它作为覆盖层淡入并逐渐变大。与您的情况类似,按照我的工作流程,在其“完全生长和可见”的状态下首先设计遮罩层元素,然后将其缩小并设置其不透明度为“隐藏”状态是有意义的。这样做,覆盖层在Base状态下是可见的,但我需要UserControl的初始状态是Hidden状态。此时,我有三个主要相关状态:Base,“Hidden”和“Visible”(这后两个是状态组的一部分)。
以下是我如何解决初始状态问题的方法。首先,我在根元素(即UserControl)上应用了GoToStateAction,该动作由Loaded事件触发。它告诉UserControl直接进入“Hidden”状态:
![enter image description here](https://istack.dev59.com/eQmay.webp)
<i:Interaction.Triggers>
<i:EventTrigger>
<ei:GoToStateAction TargetObject="{Binding ElementName=userControl}" StateName="Hidden"/>
</i:EventTrigger>
</i:Interaction.Triggers>
其次,我在叠加层的状态组中设置了适当的过渡设置。可能有几种方法可以做到这一点,但以下是我所做的。首先,我将“默认过渡”设置为令人满意的设置,比如0.4秒。接下来,我将从任何元素(在Blend中的星形图标)到此“隐藏”状态的过渡时间设置为0秒(这允许上述GoToStateAction设置“初始”状态而不使用户知道任何不同)。然后,我将从“可见”状态到“隐藏”状态的过渡设置为适当的设置(比如0.4秒)。基本上,这涵盖了所有过渡的情况。关键是确保从“任何元素”到“隐藏”状态的“过渡”是立即的,然后在从叠加层的“可见”到“隐藏”状态的情况下覆盖该立即过渡。
设置自定义控件的初始视觉状态:如果您正在开发自定义控件(而不是UserControl),因此在控件模板中定义VisualStateManager,则上述方法(根据Loaded事件启动VisualState更改)可能无法正常工作。这是因为您控件的可视树(在样式文件中定义)会在OnApplyTemplate()重写被调用之前应用于您的控件,通常是在第一个Loaded事件触发之后。因此,如果您尝试在自定义控件的Loaded事件响应中启动VisualState更改,则很可能什么也不会发生。相反,您需要在OnApplyTemplate()重写代码中启动状态更改。
public class MyCustomControl : ContentControl
{
public MyCustomControl()
{
if (DesignerProperties.GetIsInDesignMode(this))
return;
Loaded += new RoutedEventHandlerMyCustomControl_Loaded);
}
private void MyCustomControl_Loaded(object sender, RoutedEventArgs e)
{
}
public override void OnApplyTemplate()
{
if (DesignerProperties.GetIsInDesignMode(this))
return;
base.OnApplyTemplate();
VisualStateManager.GoToState(this, "MyInitialState", false);
}
}