2009-12-27 3 views
4

TabControl.ContentTemplate에 사용자 정의 컨트롤의 새 인스턴스를 추가하는 데 약간의 어려움이 있습니까?TabControl.ContentTemplate에서 새 사용자 정의 컨트롤을 추가하는 방법?

내 XAML은 여기에 있습니다 : 내가 ObservableCollection에 나는 사용자 컨트롤을 추가하고있는 콘텐츠 템플릿에 TabControl.ItemsSource 속성을 결합하고

<TabControl ItemsSource="{Binding Tables}"> 
    <TabControl.ItemTemplate> 
     <DataTemplate> 

     </DataTemplate> 
    </TabControl.ItemTemplate> 
    <TabControl.ContentTemplate> 
     <DataTemplate DataType="{x:Type uc:mytest1}"> 
      <uc:mytest1> 

      </uc:mytest1> 
     </DataTemplate> 
    </TabControl.ContentTemplate> 
</TabControl> 

하지만,이 응용 프로그램이 실행 내가 TabItem들로 새로운 아이템을 얻고 때 콘텐츠 페이지가 동일한 사용자 컨트롤을 보유하고 있지만 새 컨트롤이 새로 추가 될 때마다 TabItem이 필요합니다.

저는 WPF에 매우 익숙하며 아주 기본적인 실수를하고 있습니다. 친절하게도 저를 안내해줍니다.

답변

7

ControlTemplate은 개별 탭 항목의 일부가 아닌 탭 컨트롤 요소의 모양을 결정합니다. ItemTemplate은 개별 탭 항목의 내용을 처리합니다. 또한 TabItem은 헤더가있는 콘텐츠 컨트롤입니다. 즉 콘텐츠 형식이 ContentHeader이고 두 개의 별도 템플릿 ContentTemplateHeaderTemplate이 있습니다. 바인딩을 사용하여 탭 항목을 채울 수 있으려면 위의 속성을 사용하여 TabItem 스타일을 지정해야합니다.

<Window x:Class="Example.Window2" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Name="Window" 
    Title="Window2" Height="300" Width="300"> 
    <Window.DataContext> 
     <Binding ElementName="Window" Path="VM"/> 
    </Window.DataContext> 
    <Window.Resources> 
     <DataTemplate x:Key="TabItemHeaderTemplate"> 
      <Grid> 
       <TextBlock Text="{Binding Header}"/> 
       <Ellipse Fill="Red" Width="40" Height="40" Margin="0,20,0,0"/> 
      </Grid> 
     </DataTemplate> 
     <DataTemplate x:Key="TabItemContentTemplate"> 
      <Ellipse Fill="Green"/> 
     </DataTemplate> 
     <Style x:Key="TabItemContainerStyle" TargetType="TabItem"> 
      <Setter Property="Header" Value="{Binding}"/> 
      <Setter Property="HeaderTemplate" 
        Value="{StaticResource TabItemHeaderTemplate}"/> 
      <Setter Property="Content" Value="{Binding}"/> 
      <Setter Property="ContentTemplate" 
        Value="{StaticResource TabItemContentTemplate}"/> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <TabControl ItemsSource="{Binding Items}" 
        ItemContainerStyle="{StaticResource TabItemContainerStyle}"/> 
    </Grid> 
</Window> 

코드 뒤에 :

public partial class Window2 : Window 
{ 
    public TabControlVM VM { get; set; } 

    public Window2() 
    { 
     VM = new TabControlVM(); 
     InitializeComponent(); 
    } 
} 

그리고 뷰 모델 클래스 :

public class TabControlVM 
{ 
    public ObservableCollection<TabItemVM> Items { get; set; } 

    public TabControlVM() 
    { 
     Items = new ObservableCollection<TabItemVM>(); 
     Items.Add(new TabItemVM("tabitem1")); 
     Items.Add(new TabItemVM("tabitem2")); 
     Items.Add(new TabItemVM("tabitem3")); 
     Items.Add(new TabItemVM("tabitem4")); 
    } 
} 

public class TabItemVM 
{ 
    public string Header { get; set; } 

    public TabItemVM(string header) 
    { 
     Header = header; 
    } 
} 
3

Saurabh, 당신은 등 템플릿, 일반적으로 DataTemplate을,은 ControlTemplate을 설정하면, 이 템플릿 안의 시각적 요소는 WPF에서 UI 가상화 개념으로 재사용됩니다. TabControl은 일반적으로 한 번에 하나의 항목 만 표시하므로 모든 탭 항목에 대해 새 비주얼 항목을 만들지 않고 해당 DataContext 만 변경하고 "Selected Visual Item"의 바인딩을 새로 고칩니다. 로드/언로드 된 이벤트는 시작되지만 오브젝트는 항상 동일합니다.

로드/언로드 이벤트를 사용하고 사용자 컨트롤 인 "시각적 요소"에 맞게 코드를 작성하여 컨트롤에 상태가없고 이전 데이터에 의존하지 않아야합니다. 새로운 DataContext가 적용되면 모든 것을 새로 고쳐야합니다.

DataContextChanged, Loaded 및 언로드 이벤트는 이전 데이터에 대한 모든 종속성을 제거하는 데 도움이됩니다.

그렇지 않으면 UserControl을 Child로 수동으로 새 TabItem을 만들고 데이터 항목을 추가하는 대신 TabControl에 추가합니다.

수동으로 TabItem을 추가하면 모든 항목에 대해 새 컨트롤이 만들어지며 선택한 영역에서는 선택에 따라 다른 요소가 나타납니다.