我需要一个只显示所选项目的ItemsControl,所以我写了一个自定义的ItemsControl,如下所示:
public class TabView : ItemsControl
{
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register(
"SelectedItem",
typeof(object),
typeof(TabView),
new PropertyMetadata(new PropertyChangedCallback(SelectedItemPropertyChanged)));
private static void SelectedItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//throw new NotImplementedException();
}
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { OnSelectedItemChanged(value); }
}
public TabView()
: base()
{
}
protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
if (!IsItem(SelectedItem))
{
if (Items.Count > 0)
SelectedItem = Items[0];
else
SelectedItem = null;
}
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return false;
}
protected override DependencyObject GetContainerForItemOverride()
{
Grid grid = new Grid();
grid.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
grid.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
return grid;
}
protected virtual void OnSelectedItemChanged(object newItem)
{
if (SelectedItem == newItem) return;
if (!IsItem(newItem))
{
Debugger.Log(0, "TRACE", "TABVIEW: Index Out of Bounds"+Environment.NewLine);
return;
}
foreach (var item in Items)
{
var container = ItemContainerGenerator.ContainerFromItem(item);
if (container != null)
{
if (item == newItem)
container.SetValue(Control.VisibilityProperty, Visibility.Visible);
else
container.SetValue(Control.VisibilityProperty, Visibility.Collapsed);
}
}
SetValue(SelectedItemProperty, newItem);
}
private bool IsItem(object item)
{
return Items.Contains(item);
}
}
现在我将我的Dataobject SelectedDataTab (MainViewModel.SelectedDataTab)绑定到TabView.SelectedItem。
<uc:TabView
ItemsSource="{Binding BrowserTabs}"
SelectedItem="{Binding SelectedDataTab}">
<uc:TabView.ItemTemplate>
<DataTemplate>
<local:SlitteTabViewSelector Content="{Binding}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<local:SlitteTabViewSelector.Browser>
<DataTemplate>
<uc:CustomBrowser Margin="0,0,0,0" />
</DataTemplate>
</local:SlitteTabViewSelector.Browser>
<local:SlitteTabViewSelector.MoreTabs>
<DataTemplate>
<uc:MoreTabsControl Margin="0,0,0,0" />
</DataTemplate>
</local:SlitteTabViewSelector.MoreTabs>
</local:SlitteTabViewSelector>
</DataTemplate>
</uc:TabView.ItemTemplate>
</uc:TabView>
如果我现在开始在MainViewModel中更改 SelectedDataTab TabView.SelectedItem 将不会更改其值!我错过了什么?我想如果我将该属性绑定到我的MainViewModel.SelectedDataTab,它的值会根据绑定值进行更新。
更新:我的MainViewModel正确实现了INotifyPropertyChanged,如果更改,SelectedDataTab将触发它。
答案 0 :(得分:0)
<强>分辨强> 首先,Binding不会触发Property getter / setter,而是触发SelectedItemPropertyChanged。
但在我的代码中,SelectedItemPropertyChanged不会被解雇,因为
protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
if (!IsItem(SelectedItem))
{
if (Items.Count > 0)
SelectedItem = Items[0];
else
SelectedItem = null;
}
}
覆盖DataBinding。 ;)