在 WPF 中使用 VisualStateManager 时,可能需要在控件初始化时转换到 VisualState。据我所知,没有办法在 Xaml 中声明初始状态,在初始化之后,您只能在代码中转换到所需状态的有限选项。
使用背后的代码并不总是可取的,如果您使用绑定来控制您的 VisualStates,那么并不总是可行的。
那么问题来了:如何在WPF中设置一个初始的VisualState而不在后面的代码中设置呢?
在 WPF 中使用 VisualStateManager 时,可能需要在控件初始化时转换到 VisualState。据我所知,没有办法在 Xaml 中声明初始状态,在初始化之后,您只能在代码中转换到所需状态的有限选项。
使用背后的代码并不总是可取的,如果您使用绑定来控制您的 VisualStates,那么并不总是可行的。
那么问题来了:如何在WPF中设置一个初始的VisualState而不在后面的代码中设置呢?
评论太长了
绑定“应该”没有区别。如果它在代码隐藏中运行良好,那么它一定会在 xaml 中运行,除非绑定中有一些非常奇怪的东西。
blend 的所有动作都可以看作是一个 xaml 辅助工具。最终结果是您获得了一些混合为您创建的 xaml。如果您不想使用混合。只需在 VS 中自己添加 xaml。
为此,可以对GoToStateAction进行编码,例如
<Window ...
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
...>
...
<Button x:Name="button"
Style="{DynamicResource ButtonStyle1}">
<i:Interaction.Triggers>
<i:EventTrigger>
<ei:GoToStateAction StateName="YourState"
TargetObject="{Binding ElementName=button}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
您还需要项目中的相应引用。
顺便说一句,请尝试混合。它在特定的地方有它的优势。您 prolly 不会直接替换键入 xaml,但它是一个很好的辅助工具。除非被迫,否则完全忽略它是毫无意义的 IMO。
您可以在 xaml 中初始化时直接将任何具有可视状态的控件绑定。您需要创建一个依赖属性来更改状态。希望下面的代码可以帮助你。
<Grid model:StateManager.VisualStateProperty="{Binding VisibilityState}" >
<Grid.RowDefinitions>
<RowDefinition Height="48" />
<RowDefinition Height="97" />
<RowDefinition Height="65" />
<RowDefinition Height="297" />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisibleStateGroup">
<VisualState x:Name="VisibleState">
<Storyboard Duration="0:0:0">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="myGrid" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="CollapsedState">
<Storyboard Duration="0:0:0">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="myGrid" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Name="myGrid" Grid.Row="0" Grid.ColumnSpan="2" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="383*" />
<ColumnDefinition Width="383*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" Margin="0,0,15,0" HorizontalAlignment="Right" VerticalAlignment="Center">
<Label Content="MyName"></Label>
</StackPanel>
</Grid>
视觉状态改变的依赖属性代码
public class StateManager : DependencyObject
{
public static string GetVisualStateProperty(DependencyObject obj)
{
return (string)obj.GetValue(VisualStatePropertyProperty);
}
public static void SetVisualStateProperty(DependencyObject obj, string value)
{
obj.SetValue(VisualStatePropertyProperty, value);
}
public static readonly DependencyProperty VisualStatePropertyProperty =
DependencyProperty.RegisterAttached(
"VisualStateProperty",
typeof(string),
typeof(StateManager),
new PropertyMetadata((s, e) =>
{
var propertyName = (string)e.NewValue;
var ctrl = s as Grid;
if (ctrl == null)
throw new InvalidOperationException("This attached property only supports types derived from FrameworkElement.");
var transitionWorked = System.Windows.VisualStateManager.GoToElementState(ctrl, (string)e.NewValue, true);
//MessageBox.Show(transitionWorked.ToString());
}));
}