데이터 바인딩 및 MVVM을 사용하면 모든 것이 더 쉬워집니다. 처음에는 힘들었지 만, 궁극적으로 훨씬 쉽습니다.
Item
및 ItemCollection
의 두 클래스를 모두 INotifyPropertyChanged
으로 구현하십시오. Item
은 Text
문자열을 노출해야하며 ItemCollection
속성은 ObservableCollection<Item>
Items
속성과 Item
SelectedItem
속성을 노출해야합니다.
ItemCollection
클래스의 생성자가 테스트 데이터가있는 Items
으로 채우고 SelectedItem
으로 설정합니다.
이것은 실제로 탭 컨트롤을 구현하기 전에해야 할 일처럼 보입니다. 그러나 나를 믿으십시오. 결과를 좋아할 것입니다. TabControl에 대한 XAML은 다음과 같습니다.
<TabControl
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}">
<TabControl.DataContext>
<local:ItemsCollection/>
</TabControl.DataContext>
<TabControl.Resources>
<DataTemplate DataType="{x:Type local:Item}">
<TextBlock Background="AliceBlue" Text="{Binding Text}"/>
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Style.Setters>
<Setter Property="Header" Value="{Binding Text}"/>
</Style.Setters>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
이 기능을 이해해 봅시다. TabControl
을 만듭니다. ItemsCollection
개체를 만들고 TabControl
의 DataContext
으로 설정합니다.ItemSource
을 Items
으로 묶었으므로 TabControl
은 각 항목에 대해 TabItem
을 만듭니다. 각 TabItem
에 ItemContainerStyle
을 적용하여 Header
속성을 Item
의 Text
속성으로 설정합니다.
컨트롤이 탭의 콘텐츠를 렌더링 할 때 렌더링하는 항목을 찾고 리소스를 검색하여 이 DataType
인 항목을 찾고 해당 템플릿을 사용합니다. TabControl.Resources
에 하나를 정의 했으므로 멋진 파란색 배경과 Text
속성을 다시 얻게됩니다.
이것은 많은 문제가 될 것 같습니다. 그러나 이제는 UI를 조작하는 코드를 작성할 필요가 없습니다. ItemsCollection
을 조작하는 코드를 작성하면 UI가 거의 자체적으로 처리됩니다.
이제 새 탭을 추가해 보겠습니다. 이제 컨트롤에 새 항목을 추가하여 선택하면 Items
컬렉션에 새 항목을 추가합니다.
새 클래스 (예 : ControlItem
)를 만듭니다. Item
에서 파생 되었습니까? ItemsCollection
생성자를 수정하여 마지막 항목이 ControlItem
이되고 Item
이 아닌 값이되도록합니다. 그리고 해당 항목의 Text
속성을 "+"로 설정했는지 확인하십시오.
것은 ItemsCollection
에이 방법을 추가
public Item AddItem()
{
Item newItem = new Item {Text = "New item"};
Items.Insert(Items.Count-1, newItem);
return newItem;
}
는 이제 윈도우의 코드 숨김에 추가하고 TabControl
에 대한 SelectionChanged
이벤트 핸들러로 :
void TabControl_SelectionChanged(object sender, RoutedEventArgs e)
{
TabControl tc = (TabControl) sender;
if (tc.SelectedItem is ControlItem)
{
ItemsCollection ic = (ItemsCollection) tc.DataContext;
tc.SelectedItem = ic.AddItem();
}
}
당신은 제거 유사한 논리를 구현할 수 있습니다 목록에서 항목을 삭제할 수 있지만 삭제할 항목을 알 수 있도록 이전에 선택한 항목을 추적하려면 ItemsCollection
에 다른 변수를 추가해야합니다. 당신이 할 수있는
또 한가지 : Item
에 Background
속성을 구현하고 그것에 TabItem
의 Background
속성을 결합하는 ItemContainerStyle
에 세터를 추가합니다. 그런 다음 해당 속성을 ControlItem
에 오버로드하여 추가 및 삭제 탭이 다르게 표시되도록 할 수 있습니다.
컨트롤 항목에 대해 다른 하위 클래스를 구현하고 SelectionChanged
이벤트 처리기에서 호출하는 메서드를 노출시킬 수도 있습니다. 이렇게하면 이벤트 핸들러는 클릭되는 컨트롤 항목이 수행중인 작업에 대해 아무 것도 알 필요가 없습니다. 실제로 메소드가 Item
의 일부가되고 오버라이드하지 않는 한 아무 작업도 수행하지 않으면 윈도우가 Item
에 하위 클래스가 있음을 알 필요조차 없습니다.
MVVM의 철학은 간단합니다. 거의 아무것도 모르는 객체에 뷰를 바인딩합니다. 뷰 모델 객체가 어떤 일이 일어나도록 제어하므로 뷰가 반드시 필요하지 않습니다.
'TabItem'에는 비극적으로'Click' 이벤트가 없습니다. 그것은'Selected' 이벤트조차 가지고 있지 않습니다. 사용자가 탭을 클릭 할 때 응답하는 것은 'TabControl'에 달려 있습니다. 또한 탭을 클릭하고 키보드로 탭으로 이동하는 것을 구별하지 않습니다.이 경우에는 제스처가 다른 결과를 나타 내기를 원하면 불행합니다. –
안녕하세요. Gishu, 도움을 주셔서 감사합니다.다른 문제가 발생하더라도 구현을 시도 할 때 내 다음 질문에서 언급 한 이유로 ComboBox에 액세스 할 수 없다는 것을 알게되었습니다. -> http://stackoverflow.com/questions/2302876/datagrid-editable-issue-access-issue- in-wpf. 제발 도와주세요. 정말 고마워. – user276916
@ 로버트 - 아! 그걸 몰랐어 - 제니, 난 WPVM에서 쉽게 할 수있는 모든 사소한 것들을 얻으려면 MVVM (그 조쉬 스미스의 기사 검색)에 읽어야 할 것 같아요 – Gishu