0

我需要一个只显示所选项目的 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 TabView.SelectedItem中的SelectedDataTab不会改变它的值!我错过了什么?我想如果我将该属性绑定到我的 MainViewModel.SelectedDataTab 它的值会根据绑定值进行更新。

更新:我的 MainViewModel 正确实现了 INotifyPropertyChanged,如果更改,SelectedDataTab 将触发它。

4

1 回答 1

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;
    }
}

覆盖数据绑定。;)

于 2012-12-20T13:42:45.497 回答