2016-07-24 140 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); 
     } 
    } 
    ... 
}