2016-07-19 13 views
1

Platzieren Sie ein UserControl innerhalb eines TabItem ist ziemlich einfach, wenn Sie XAML verwenden.Load UserControl in TabItem programmgesteuert

<TabControl> 
    <TabItem> 
     <local:MyUserControl/> 
    </TabItem> 
</TabControl> 

Aber sagen, ich möchte das UserControl mit dem ViewModel laden. Wie würde ich darüber gehen? Zum Beispiel

<TabControl ItemsSource="{Binding TabCollection}"> 
    <TabItem Header="{Binding Header}" 
      Source="{Binding MyUserControl}"> <!-- Source is obviously not a property of TabItem--> 
               <!-- I'm just using it in this context as an example. Like how a 'Frame' would work --> 
    </TabItem> 
</TabControl> 

Mein Ansichtsmodell Unter der Annahme hat eine ObservableCollection, die ich die verschiedenen Tabs zu füllen verwenden, Header, Hintergrundfarbe und so weiter, wie würde ich einen Blick in die TabItem programmatisch zu füllen?

Zum Beispiel Unten finden Sie eine grundlegende Probe des Ansichtsmodell:

public class TabViewModel 
{ 
    // 'TabModel' is a simple class that acts as a Model for this class (TabViewModel) 
    // All it does is store strings, integers, etc. as properties 
    // i.e: the fields 'Header' and 'MyUserControl' in the below method are both strings declared in 'TabModel' 
    public ObservableCollection<TabModel> TabCollection { get; set; } 

    public TabViewModel() 
    { 
     TabCollection = new ObservableCollection<TabModel>(); 
     PopulateTabCollection(); 
    } 

    private void PopulateTabCollection() 
    { 
     TabCollection.Add(new TabModel() 
     { 
      Header = "FirstUserControl", 
      MyUserControl = "Views/MyFirstUserControl.xaml" 
     }); 

     TabCollection.Add(new TabModel() 
     { 
      Header = "SecondUserControl", 
      MyUserControl = "Views/MySecondUserControl.xaml" 
     }); 
    } 
} 

Also, was ich tun muss, ist in jedem Tab durch Datenbindung eine andere Ansicht anzuzeigen. Ich bin mir nicht einmal sicher, ob das überhaupt möglich ist. Aber wenn es so ist, bitte erziehe mich.

Antwort

2

Sie können dies mit DataTemplates erreichen. Siehe den folgenden Code.

<Window.Resources> 
    <DataTemplate DataType="{x:Type local:PersonVm}"> 
     <local:Person/> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type local:DeptVm}"> 
     <local:Department/> 
    </DataTemplate> 
</Window.Resources> 
<Grid> 
    <TabControl ItemsSource="{Binding TabCollection}" SelectedIndex="0"> 
     <TabControl.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding TabName}"/> 
      </DataTemplate> 
     </TabControl.ItemTemplate> 
     <TabControl.ContentTemplate> 
      <DataTemplate> 
       <ContentControl Content="{Binding }"/> 
      </DataTemplate> 
     </TabControl.ContentTemplate> 
    </TabControl> 
</Grid> 


public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = new TabViewModel(); 
     } 
    } 

    public class TabViewModel 
    { 
     public ObservableCollection<object> TabCollection { get; set; } 

     public TabViewModel() 
     { 
      TabCollection = new ObservableCollection<object>(); 
      PopulateTabCollection(); 
     } 

     private void PopulateTabCollection() 
     { 
      TabCollection.Add(new PersonVm() 
      { 
       PersonName = "FirstUserControl", 
       Address = "Address", 
       TabName = "Person Tab" 
      }); 

      TabCollection.Add(new DeptVm() 
      { 
       DeptName = "SecondUserControl", 
       TabName = "DeptTab" 
      }); 
     } 
    } 

    public class PersonVm 
    { 
     public string PersonName { get; set; } 
     public string Address { get; set; } 
     public string TabName { get; set; } 

    } 

    public class DeptVm 
    { 
     public string DeptName { get; set; } 
     public string TabName { get; set; } 
    } 
+0

Nicht ganz, was ich im Sinn hatte, aber das gibt mir die Ergebnisse, die ich suchte. Ich hatte wohl den Eindruck, dass das ViewModel das Verzeichnis der Ansicht als String übergeben musste. Aber dieser Weg funktioniert eigentlich ganz gut. Vielen Dank. – Offer