2010-12-04 25 views
2

私はその背後にビューモデルを持つ再利用可能なusercontrolを持っています。私は同じデータの異なるビューを切り替えることを試みています。現在、これを達成するためにVMでModeプロパティを使用しようとしています。ユーザーコントロール内の同じViewModelの2つのビュー

は、私はそうのようなDataTemplateSelectorを作成しました:

class DisplayTemplateSelector : DataTemplateSelector 
{ 

    public DataTemplate ColumnTemplate {get;set;} 

    public DataTemplate AvatarTemplate {get;set;} 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     MainViewModel vm = (MainViewModel)item; 

     switch (vm.Mode) 
     { 
      case MainViewModel.DisplayMode.Column: 
       return ColumnTemplate; 
      case MainViewModel.DisplayMode.Avatar: 
       return AvatarTemplate; 
      default: 
       return AvatarTemplate; 
     } 
    } 

} 

このユーザーコントロールは、mywindowの中で座っている:クラスで

<UserControl x:Class="MyUserControl"> 
    <UserControl.Resources> 
     <DataTemplate x:Key="ColumnTemplate"> 
      <StackPanel> 
       <Label Text="{Binding Name}"></Label> 
       <Label Text="{Binding Address}"></Label> 
       <Label Text="{Binding Occupation}"></Label> 
      </StackPanel> 
     </DataTemplate> 
     <DataTemplate x:Key="AvatarTemplate"> 
      <StackPanel> 
       <Image Source="{Binding ProfilePicture}"></Image> 
       <Label Text="{Binding Name}"></Label> 
      </StackPanel> 
     </DataTemplate> 
    <local:DisplayTemplateSelector ColumnTemplate="{StaticResource ColumnTemplate}" AvatarTemplate="{StaticResource AvatarTemplate}" x:Key="displayTemplateSelector" /> 
</UserControl.Resources> 
<Grid> 
    <ContentControl Name="cpDisplay" Content="{Binding}" ContentTemplateSelector="{StaticResource displayTemplateSelector}" /> 
</Grid> 
</UserControl> 

私のviewmodelでインスタンス化され

<Grid> 
    <controls:MyUserControl x:Name="MyUserControl" DataContext="{Binding}" Margin="0"/> 
</Grid> 

MyWindow w = new MyWindow(_vm); 
w.Show(); 

問題はitemMainViewModel vm = (MainViewModel)itemの間nullであることです。データがバインドされる前に、データに基づいてデータテンプレートを設定しようとしているようなものですか?

データオブジェクトに基づいていない - ユーザーコントロールのプロパティまたは同様のものとして、目的のデータテンプレートを選択する方法はありますか?

答えて

2

そこに多くの方法がありますが、ここでカップルされています

<!-- assumes you have a data template selector implementation available as resource MyContentSelector --> 
<ContentControl Content="{StaticResource MainViewModel}" ContentTemplateSelector="{StaticResource MyContentSelector}"/> 

または:[OK]を、最終的に仕事にこれを

<!-- assumes you have appropriate boolean properties on your VM --> 
<Grid> 
    <ContentControl Content="{StaticResource MainViewModel}" ContentTemplate="{StaticResource column}" Visibility="{Binding IsColumnVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/> 
    <ContentControl Content="{StaticResource MainViewModel}" ContentTemplate="{StaticResource avatar}" Visibility="{Binding IsAvatarVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/> 
</Grid> 
+0

みんなありがとうを、これはUIモードを制御する唯一の方法は、ビューモデルのプロパティを設定することであることを意味しますか?もしそうなら、それもそうです。 – DaveO

+0

2番目の解決策は、私が最後にやったことにつながります。 – DaveO

0

ましたどのように私は、usercontrolといくつかのコードの背後にあるプロパティを使用して必要な:

public enum DisplayMode 
    { 
     Column, 
     Avatar 
    } 

    public DisplayMode Mode { get; set; } 


    public MyUserControl() 
    { 
     InitializeComponent(); 
     Mode = DisplayMode.Avatar; 
    } 

    private void MyUserControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     switch (Mode) 
     { 
      case DisplayMode.Column: 
       cpDisplay.ContentTemplate = (DataTemplate)this.Resources["ColumnTemplate"]; 
       cpDisplay.ApplyTemplate(); 
       break; 
      case DisplayMode.Avatar: 
       cpDisplay.ContentTemplate = (DataTemplate)this.Resources["AvatarTemplate"]; 
       cpDisplay.ApplyTemplate(); 
       break; 
     } 
    } 

私はDataTemplateSelectorコードを削除し、単にdatatemplatesを定義し、使用:

<ContentPresenter Name="cpDisplay" Content="{Binding}" /> 
関連する問題