ObservableCollection和Binding的问题

本文关键字:问题 Binding ObservableCollection | 更新日期: 2023-09-27 18:17:57

我有一个class Mod定义为

public class Mod
{
    public Mod()
    {
        Data = new ObservableCollection<object>();
    }
    public Mod(Mod other)
    {
        Data = new ObservableCollection<object>(other.Data);
    }
    public ObservableCollection<object> Data { get; private set; }
}

和一个控制

    <TreeView x:Name="ItemList" DockPanel.Dock="Left" DataContext="{Binding Mod, Source={StaticResource Core}}" >
        <TreeView.Resources>
            <DataTemplate x:Key="TVTemplate" >
                <TreeViewItem Header="{Binding Name}" Tag="{Binding }" ToolTip="{Binding Desc}" />
            </DataTemplate>
        </TreeView.Resources>
        <TreeViewItem Header="Item1" ItemsSource="{Binding Data, ConverterParameter={x:Type local:Item1Type}, Converter={StaticResource OMTypeConverter}}" ItemTemplate="{DynamicResource TVTemplate}"/>
        <TreeViewItem Header="Item2" ItemsSource="{Binding Data, ConverterParameter={x:Type local:Item2Type}, Converter={StaticResource OMTypeConverter}}" ItemTemplate="{DynamicResource TVTemplate}"/>

类型转换器定义为

public class OMTypeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        List<object> rtn = new List<object>();
        ObservableCollection<object> data= value as ObservableCollection<object>;
        if (data!= null)
        {
            Type type = parameter as Type;
            if (type != null)
            {
                var tmp = data.Where(o => type.IsInstanceOfType(o));
                rtn.AddRange(tmp);
            }
        }
        return rtn;
    }
}

当加载窗口时,它完美地工作,类型转换器显示一个值,是一个空的可观察对象集合,然而,当我然后添加一个项目到OC什么都没有发生,转换器没有被调用,项目列表在屏幕上显示不变

我已经从后面的代码中确认值已添加到数据集合

那么为什么绑定没有被触发来更新treeveiwitem呢?

ObservableCollection和Binding的问题

在您的转换器中,您正在断开与原始集合的链接。

我可以想到一些变通方法,但有一个干净的解决方案。

你应该在Data上使用两个集合视图

在代码后面声明它们:

public ICollectionView Item1TypeView { get; set; }
public ICollectionView Item2TypeView { get; set; }

并在视图的构造函数中初始化它们:

Item1TypeView = new CollectionViewSource { Source = Data }.View;
Item1TypeView.Filter = e => e is Item1Type;
Item2TypeView = new CollectionViewSource { Source = Data }.View;
Item2TypeView.Filter = e => e is Item2Type;

然后将每个TreeView绑定到其中一个:

<TreeViewItem Header="Item1" ItemsSource="{Binding Item1TypeView}" ItemTemplate="{DynamicResource TVTemplate}"/>
<TreeViewItem Header="Item2" ItemsSource="{Binding Item2TypeView}" ItemTemplate="{DynamicResource TVTemplate}"/>