不能跟踪在CustomControl WPF中向列表添加项/从列表中删除项

时间:2018-09-17 23:01:55

标签: c# wpf

我在CustomControl的类中有一个ObservationCollection。

 public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection<Draggable>), typeof(Draggable), new PropertyMetadata(new ObservableCollection<Draggable>(), OnItemsChanged));

    private static void OnItemsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        Draggable draggable = (Draggable)obj;

        if (e.NewValue != null)
        {
            if (((ObservableCollection<Draggable>)e.NewValue).Count > 0)
                draggable.HasItem = true;
            else
                draggable.HasItem = false;
        }
        else
        {
            draggable.Items = new ObservableCollection<Draggable>();
            draggable.HasItem = false;
        }
    }

,默认情况下,它已由new ObservableCollection<Draggable>分配。

我无法跟踪向/从此集合添加或删除项目的过程。

每当我为此属性分配新的ObservableCollection时,都会触发

OnItemsChanged。因此添加或删除商品不会为我带来任何好处。

我还有一个名为HasItem的属性。每当此属性为True但永远不会为True时,我将在ControlTemplate中显示一个Grid。

我该如何解决这个问题?

编辑:

我的主类是Draggable,并且ObservableCollection的类型相同。 我尝试了两种解决方案:

  1. 我已经写了一个ValueConverter:

    [ValueConversion(typeof(ObservableCollection),typeof(Visibility))] 公共类IntToVisibilityConverter:IValueConverter {     公共静态IntToVisibilityConverter实例= new IntToVisibilityConverter();

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ObservableCollection<Draggable> Source = (ObservableCollection<Draggable>)value;
        if (Source.Count > 0)
            return Visibility.Visible;
        else
            return Visibility.Collapsed;
    }
    
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
    

    }

我以这种方式使用它:

 <Border x:Name="ItemsContainer" Visibility="{Binding Path=Items,Converter={x:Static MyConverters:IntToVisibilityConverter.Instance}}" ... >
  1. 我为类编写了一个构造函数,并添加了CollectionChanged事件:

    public Draggable()
    {
        Items.CollectionChanged += Items_CollectionChanged;
    }
    
    private void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (Items.Count > 0)
            HasItem = true;
        else
            HasItem = false;
    }
    
正如Visual Studio所说,它们

都将陷入无限循环。 我不明白这一点,因为我看不到它说的循环。

2 个答案:

答案 0 :(得分:0)

仅当设置依赖项属性时,才设置HasItem。我猜想您希望它在集合的内容更改时(例如,通过添加或删除项目)重新计算该值。

如果您仅需要Xaml的服务,那么我就不会为HasItem属性烦恼:只需使用ValueIsNotZeroConverter将Grid的可见性绑定到DP的Count属性,即可将{ 1}}到int

答案 1 :(得分:0)

OnItemsChanged将在属性值更改时触发(对于ObservableCollection,如果将新值分配给ObservableCollection属性)。为了获得有关在ObservableCollection上添加或删除项的通知,我们必须注册ObservableCollection类的CollectionChanged事件。例如

private static void OnItemsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            Draggable draggable = (Draggable)obj;

            if (e.NewValue != null)
            {
                if (((ObservableCollection<Draggable>)e.NewValue).Count > 0)
                {
                    draggable.HasItem = true;
                    (ObservableCollection<Draggable>)e.NewValue).CollectionChanged += CollectionChanged;
                }
                else
                    draggable.HasItem = false;
            }
            else
            {
                draggable.Items = new ObservableCollection<Draggable>();
                draggable.HasItem = false;
            }
        }
private void CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {

        }