【问题标题】:bounding tab control items to a PROPERTY of an ObservableCollection, with a twist将选项卡控件项绑定到 ObservableCollection 的 PROPERTY,并带有一个扭曲
【发布时间】:2015-09-06 07:28:19
【问题描述】:

我有一个TabControl

我按照here 的答案选择了这封信。问题是,在我的情况下,ExistingTabs 不是 ObservableCollection,而是 ObservableCollection 的 property

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。

谢谢。

【问题讨论】:

  • 你是想要 TwoWay 绑定来收集,还是足够 OneWay 绑定?
  • @VMaleev:单向就足够了。选项卡控件没有“删除”功能,所有的变化都是从 observablecollection 到 UI 发生的。
  • 还有一个:你真的需要 testData 是静态的吗?
  • 我认为有错字:public class ReportData 应该是 public class ReportDataSet?
  • 静态:是的。对不起。关于 ReportData - 不。它是一个包含大量信息的对象,其中一个是 testData。

标签: c# wpf binding tabcontrol compositecollection


【解决方案1】:

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

希望对你有帮助

【讨论】:

  • 嗨.. 它告诉“命名空间中不存在名称 CollectionConverter .....”
  • 你添加了它,添加了“本地”命名空间并重建了项目吗? =)
  • 您可以接受 Skype 或 teamviewer 会话吗?
  • CollectionConverter 和你的窗口是否在同一个命名空间中?如果不是,它们是否在同一个程序集中?如果不是,你是如何指定 xmlns 的?
  • Here's 我的测试项目给你。添加和删​​除选项卡项目工作正常。由于您无法共享您的代码,也不允许我帮助您,因此如果出现问题,您必须自己搜索代码中可能存在的错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-21
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多