将选项卡控件项绑定到 ObservableCollection 的 属性

bounding tab control items to a PROPERTY of an ObservableCollection, with a twist

我有一个TabControl

我按照选择的答案 here 写了这封信。问题是,在我的例子中,ExistingTabs 不是 ObservableCollection,而是 ObservableCollection 的 属性:

Public Class TestData : INotifyPropertyChanged // and the required event handler is there also, not shown here
{
    public TabItem tiTestTab {get; set;}
    // another dozen properties
}

public class ReportData
{
    public static ObservableCollection<TestData> testData {get;set;}
    // another dozen properties
}

这是我所做的:

<Window.Resources>
   <CollectionViewSource x:Key="ExistingTabs" Source="{Binding Path=(local:ReportDataSet.testData), Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Window.Resources>
<TabControl>
    <TabControl.ItemsSource>
        <CompositeCollection>
             <TabItem>SomeSpecialItem</TabItem>
             <CollectionContainer Collection="{Binding Source={StaticResource ExistingTabs}}"/>
         </CompositeCollection>
    </TabControl.ItemsSource>
</TabControl>

当然,这会将 testData 放在选项卡中,而不是 tiTestTab 属性。

我很茫然

最好只 XAML。 使用 C# 和 Visual Studio 2013.

谢谢。

Xaml代码:

<Window.Resources>
    <local:CollectionConverter x:Key="collectionConverter" />
    <CollectionViewSource x:Key="ExistingTabs" Source="{Binding Path=(local:ReportDataSet.testData), Converter={StaticResource collectionConverter}, UpdateSourceTrigger=PropertyChanged}"/>
</Window.Resources>
<TabControl>
    <TabControl.ItemsSource>
        <CompositeCollection>
            <TabItem Header="test">
                <StackPanel>
                    <Button Content="Add new item" Click="AddNewTabItem"></Button>
                    <Button Content="Remove last item" Click="RemoveLastItem"></Button>
                </StackPanel>
            </TabItem>
            <CollectionContainer Collection="{Binding Source={StaticResource ExistingTabs}}" >
            </CollectionContainer>
        </CompositeCollection>
    </TabControl.ItemsSource>
</TabControl>

转换器:

public class CollectionConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ObservableCollection<TestData>)
        {
            return new ObservableCollection<TabItem>(((ObservableCollection<TestData>)value).
                Select(q => q.tiTestTab));
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

报告数据集:

public class ReportDataSet
{
    public static ObservableCollection<TestData> testData { get; set; }

    static ReportDataSet()
    {
        testData = new ObservableCollection<TestData>();
        testData.Add(new TestData()
        {
            tiTestTab = new TabItem()
            {
                Header = "test 1"
            }
        });

        testData.CollectionChanged += (s, e) => { OnStaticPropertyChanged("testData"); };
    }
    public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

    protected static void OnStaticPropertyChanged(string propertyName)
    {
        var handler = StaticPropertyChanged;
        if (handler != null) handler(null, new PropertyChangedEventArgs(propertyName));
    }
}

代码隐藏(用于测试目的):

    private void AddNewTabItem(object sender, RoutedEventArgs e)
    {
        ReportDataSet.testData.Add(new TestData()
        {
            tiTestTab = new TabItem()
            {
                Header = "test " + (ReportDataSet.testData.Count + 1)
            }
        });
    }

    private void RemoveLastItem(object sender, RoutedEventArgs e)
    {
        if (ReportDataSet.testData.Count == 0) return;

        ReportDataSet.testData.Remove(ReportDataSet.testData.Last());
    }

希望,有帮助