【问题标题】:Switching between states in UserControls在 UserControls 中切换状态
【发布时间】:2016-07-30 03:53:16
【问题描述】:

我的应用程序显示了一个用户控件来添加一个新对象。添加对象后,它会显示创建对象的属性。

状态 1:空 UserControl

状态 2:填充用户控件

我想有两种方法可以实现这样的事情:

  1. 创建 1 个具有 2 种不同视觉状态的用户控件 - 根据控件是否包含对象实例在状态之间切换
  2. 创建 2 个没有状态的用户控件并显示当前需要的那个。这需要一些更高级别的控制机制来添加/删除正确的控制。

在这种情况下,最佳做法是什么?做一个或另一个有什么缺点/优点?还有其他我没想到的方法吗?

【问题讨论】:

    标签: c# wpf user-controls state


    【解决方案1】:

    我会在UserControl.Resources 中创建两个数据模板并用触发器交换它们。 CreateUserTemplate 只是有一个绑定到CreateUserCommand 的按钮,或者一个点击事件。 EditUserTemplate 是用户编辑模板。没有路径的Content="{Binding}" 使用DataContext 作为Content。如果我有你的视图模型的确切细节,我可以给你更多关于你如何在这里获取内容的细节。

    我还假设视图模型具有可为空的 UserID 属性。

    <ContentControl
        Content="{Binding}"
        >
        <ContentControl.Style>
            <Style TargetType="ContentControl">
                <!-- Default has to go in a setter in the Style, not an 
                     attribute on the ContentControl tag -->
                <Setter 
                    Property="ContentTemplate" 
                    Value="{StaticResource EditUserTemplate}" 
                    />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding UserID}" Value="{x:Null}">
                        <Setter 
                            Property="ContentTemplate" 
                            Value="{StaticResource CreateUserTemplate}" 
                            />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>
    

    您可以改为编写 DataTemplateSelector,但对于这种微不足道的事情,我发现在 XAML 中执行所有操作更容易。

    【讨论】:

      【解决方案2】:

      为此,WPF 提供了VisualStateManager

      <UserControl ...>
          <Grid>
              <VisualStateManager.VisualStateGroups>
                  <VisualStateGroup Name="States">
                      <VisualState x:Name="WithoutObject">
                          <Storyboard>
                              <ObjectAnimationUsingKeyFrames Storyboard.TargetName="WithoutObjectPanel" Storyboard.TargetProperty="Visibility">
                                  <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                      <DiscreteObjectKeyFrame.Value>
                                          <Visibility>Visible</Visibility>
                                      </DiscreteObjectKeyFrame.Value>
                                  </DiscreteObjectKeyFrame>
                              </ObjectAnimationUsingKeyFrames>
                              <ObjectAnimationUsingKeyFrames Storyboard.TargetName="WithObjectPanel" Storyboard.TargetProperty="Visibility">
                                  <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                      <DiscreteObjectKeyFrame.Value>
                                          <Visibility>Collapsed</Visibility>
                                      </DiscreteObjectKeyFrame.Value>
                                  </DiscreteObjectKeyFrame>
                              </ObjectAnimationUsingKeyFrames>
                          </Storyboard>
                      </VisualState>
                      <VisualState x:Name="WithObject">
                          <Storyboard>
                              <ObjectAnimationUsingKeyFrames Storyboard.TargetName="WithoutObjectPanel" Storyboard.TargetProperty="Visibility">
                                  <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                      <DiscreteObjectKeyFrame.Value>
                                          <Visibility>Collapsed</Visibility>
                                      </DiscreteObjectKeyFrame.Value>
                                  </DiscreteObjectKeyFrame>
                              </ObjectAnimationUsingKeyFrames>
                              <ObjectAnimationUsingKeyFrames Storyboard.TargetName="WithObjectPanel" Storyboard.TargetProperty="Visibility">
                                  <DiscreteObjectKeyFrame KeyTime="0:0:0">
                                      <DiscreteObjectKeyFrame.Value>
                                          <Visibility>Visible</Visibility>
                                      </DiscreteObjectKeyFrame.Value>
                                  </DiscreteObjectKeyFrame>
                              </ObjectAnimationUsingKeyFrames>
                          </Storyboard>
                      </VisualState>
                  </VisualStateGroup>
              </VisualStateManager.VisualStateGroups>
      
              <StackPanel x:Name="WithoutObjectPanel" Visibility="Hidden">
                  <TextBlock Text="Without object :("/>
              </StackPanel>
      
              <StackPanel x:Name="WithObjectPanel" Visibility="Visible">
                  <TextBlock Text="With object :) !!!!"/>
              </StackPanel>
          </Grid>
      </UserControl>
      

      UserControl.cs

      public partial class UserControl1 : UserControl
      {
          object _anObject;
          public object AnObject 
          { 
              get { return _anObject; } 
              set { _anObject = value; 
                  if(value == null) VisualStateManager.GoToState(this, "WithoutObject", true);
                  else VisualStateManager.GoToState(this, "WithObject", true); 
              } 
          }
          ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-04
        相关资源
        最近更新 更多