3

我一直在编写一个小的 Silverlight 帮助器类来实现一个附加属性,该属性可以绑定到ICollection/INotifyCollectionChanged并在绑定集合为空时切换目标对象的可见性。

我没有完全掌握DependencyProperty有关内存管理和对象生命周期的行为。

这是来源:

public class DisplayOnCollectionEmpty : DependencyObject
{
    #region Constructor and Static Constructor

    /// <summary>
    /// This is not a constructable class, but it cannot be static because 
    /// it derives from DependencyObject.
    /// </summary>
    private DisplayOnCollectionEmpty()
    {
    }

    #endregion

    public static object GetCollection(DependencyObject obj)
    {
        return (object)obj.GetValue(CollectionProperty);
    }

    public static void SetCollection(DependencyObject obj, object value)
    {
        obj.SetValue(CollectionProperty, value);
    }

    // Using a DependencyProperty as the backing store for Collection.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CollectionProperty =
    DependencyProperty.RegisterAttached("Collection", typeof(object), typeof(FrameworkElement), new PropertyMetadata(OnCollectionPropertyChanged));

    private static void OnCollectionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement fe = d as FrameworkElement;

        NotifyCollectionChangedEventHandler onCollectionChanged = (sender, collectionChangedEventArgs) =>
        {
            fe.Visibility = GetVisibility(e.NewValue as ICollection);
        };

        if (e.OldValue is INotifyCollectionChanged)
        {
            ((INotifyCollectionChanged)e.OldValue).CollectionChanged -= onCollectionChanged;
        }
        if (e.NewValue is INotifyCollectionChanged)
        {
            ((INotifyCollectionChanged)e.NewValue).CollectionChanged += onCollectionChanged;
        }

        fe.Visibility = GetVisibility(e.NewValue as ICollection);
    }

    private static Visibility GetVisibility(ICollection collection)
    {
        if (collection == null) return Visibility.Visible;
        return collection.Count < 1 ? Visibility.Visible : Visibility.Collapsed;
    }
}
4

1 回答 1

1

看起来您在设置集合时订阅了 INotifyCollectionChanged 的​​ CollectionChanged,并且只有在更改集合时才取消订阅。

我还将通过从 CollectionChanged 事件中注销来处理 FrameworkElement 的 Unloaded 事件。

我看到您没有检查 e.OldValue 或 e.NewValue 是否为空。

出于同样的目的,您可以使用行为来代替依赖属性。我的想法主要是一样的。我还没有考虑过利弊。以下是一些关于行为与依赖属性的有趣链接: Interactivity.Behavior<T> 与附加属性

https://web.archive.org/web/20130622113553/http://briannoyes.net/2012/12/20/AttachedBehaviorsVsAttachedPropertiesVsBlendBehaviors.aspx

于 2013-01-25T07:59:19.520 回答