2016-07-24 130 views
0

我的应用程序显示一个UserControl添加一个新的对象。一旦添加了对象,它就会显示创建的对象的属性。UserControls中的状态切换

状态1:空用户控件
Empty UserInput

状态2:填充用户控件
Filled UserInput

我估计有2种方式,我可以实现这样的事情:

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

这种情况下的最佳做法是什么?做这个或那个有什么好处/好处?还有其他方式,我还没有想到呢?

回答

1

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

我还假设viewmodel有一个可为空的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中做的一切。

1

为此特定目的,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); 
     } 
    } 
    ... 
}