所有數據綁定和MVVM都更容易。開始時更加困難,但最終更容易。
製作兩個類,Item
和ItemCollection
,它們都實現了INotifyPropertyChanged
。 Item
應該公開一個字符串Text
屬性,而ItemCollection
應該公開一個ObservableCollection<Item>
Items
屬性和一個Item
SelectedItem
屬性。
使ItemCollection
類的構造函數填充Items
與測試數據和設置SelectedItem
。
在實際使用tab控件之前,這似乎有很多事情要做,但請相信我,您會喜歡這個結果。您的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
。它創建一個對象並將其設置爲TabControl
的DataContext
。您已綁定ItemSource
至Items
,因此TabControl
將爲每個項目創建一個TabItem
。它將應用ItemContainerStyle
每個TabItem
,這將其Header
屬性設置爲Item
的Text
財產。
當控件呈現一個選項卡的內容,它發現它的渲染項,搜索整個資源,找到一個DataTemplate
其DataType
的項目相匹配,並使用該模板。由於我們在TabControl.Resources
中定義了一個,所以您會再次獲得一個很好的藍色背景和Text
屬性。
這似乎很多要經過。但是現在您不必編寫任何操作UI的代碼;你只需編寫代碼來操縱你的UI,而且UI幾乎可以自己處理。
現在,讓我們添加新的選項卡的照顧。我們要做的是向控件添加一個新項目,當它被選中時,將向Items
集合添加一個新項目。
創建一個新的類,叫哦,ControlItem
。它來自Item
。修改您的構造函數,以便它添加的最後一項是ControlItem
,而不是Item
。並讓它將該項目的Text
屬性設置爲「+」。
此方法添加到:
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();
}
}
您可以實現類似的邏輯刪除列表中的一個項目,但您需要引入另一個變量來追蹤之前選擇的項目,以便您可以知道要刪除哪個項目。
你可以做的另一件事:實現Background
財產Item
和setter方法添加到該TabItem
的Background
屬性綁定到它的ItemContainerStyle
。然後,您可以在ControlItem
中重載該屬性,以便添加和刪除選項卡看起來不同。
您還可以爲您的控件項目實現不同的子類,並讓他們公開您在SelectionChanged
事件處理程序中調用的方法。這樣,事件處理程序不必知道被點擊的控件項目在做什麼。事實上,如果你使方法成爲Item
的一部分,並且除非被覆蓋,否則它什麼都不做,窗口甚至不需要知道Item
具有的子類。
這就是MVVM背後的哲學:將視圖綁定到它幾乎什麼都不知道的對象上。讓視圖模型對象控制發生的事情,以便視圖不必。
不幸的是,'TabItem'沒有'Click'事件。它甚至沒有「Selected」事件。當用戶點擊一個標籤時,由TabControl控制。它也不區分點擊標籤和用鍵盤導航到標籤,如果你希望這些手勢有不同的結果,這是不幸的,就像你在這種情況下那樣。 – 2010-02-19 23:32:58
嗨Gishu,謝謝你的幫助。雖然出現了另一個問題,但當我嘗試執行並發現由於我的下一個問題中提到的原因而無法訪問我的ComboBox時 - > http://stackoverflow.com/questions/2302876/datagrid-editable-issue-access-issue- in-wpf。請幫助。非常感謝。 – user276916 2010-02-20 16:49:41
@Robert - 啊!不知道--Geny,我想你必須閱讀MVVM(搜索Josh Smith的文章),以便在WPF中輕鬆完成所有不平凡的事情 – Gishu 2010-02-22 06:49:08