在WPF中设置初始VisualState

在WPF中设置初始VisualState,wpf,visualstatemanager,Wpf,Visualstatemanager,在WPF中使用VisualStateManager时,可能需要在控件初始化时转换到VisualState。据我所知,没有办法在Xaml中声明初始状态,这使得您在初始化后只能在代码中有限地转换到所需状态 使用代码隐藏并不总是可取的,如果您使用绑定来控制您的VisualState,那么并不总是可行的 所以问题是:如何在WPF中设置初始VisualState而不在代码隐藏中设置它?太长,无法发表评论 绑定“应该”没有区别。如果它可以从代码隐藏中正常工作,那么它一定可以从xaml中正常工作,除非绑定中有

在WPF中使用VisualStateManager时,可能需要在控件初始化时转换到VisualState。据我所知,没有办法在Xaml中声明初始状态,这使得您在初始化后只能在代码中有限地转换到所需状态

使用代码隐藏并不总是可取的,如果您使用绑定来控制您的VisualState,那么并不总是可行的

所以问题是:如何在WPF中设置初始VisualState而不在代码隐藏中设置它?

太长,无法发表评论

绑定“应该”没有区别。如果它可以从代码隐藏中正常工作,那么它一定可以从xaml中正常工作,除非绑定中有一些非常奇怪的东西

blend的所有操作都可以看作是xaml辅助工具。最终的结果是您得到了blend为您创建的一些xaml。如果不想使用“混合”。只需将xaml添加到VS中即可

对于这一点,可以将

<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>

...
在项目中也需要相应的引用


在旁注上尝试混合。它在特定的地方有它的优势。通常不会直接替换键入xaml,但它是一个很好的辅助工具。除非被迫忽略它,否则完全忽略它是毫无意义的。

您可以在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>

不确定我是否正确地遵循了这一点,但您是否正在尝试在启动时转换到状态而不使用代码隐藏?如果是这样,您可以使用
GoToStateAction
并将事件触发器设置为加载
并选择相应的状态。这就是你想要的吗?这就是我想要做的,但是要增加一点复杂性,初始状态依赖于一个绑定属性。你给出的解决方案使用的是我不使用的混合液,我也不熟悉。如果不用的话,我真的不想用它。谢谢你的建议,谢谢。我在VS中引用了表达式程序集,我认为这是一个很好的折衷方案。
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());
          }));
    }