【发布时间】:2012-12-22 05:52:23
【问题描述】:
我一直在编写一个小的 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;
}
}
【问题讨论】:
-
几点注意事项: 1. 声明附加属性的类不需要派生自DependencyObject。因此不需要私有构造函数。 2.RegisterAttached中的ownerType(3rd)参数必须是声明类,这里是DisplayOnCollectionEmpty,不是FrameworkElement。
-
为什么不直接将 FrameworkElement 的 Visibility 绑定到 Collection 并使用适当的 binding converter?
-
@Clemens :我不使用 IValueConverter 因为我还想在更新集合时更改值,AFAIK 我不能用 IValueConverter 做到这一点,因为它不公开目标 DependencyObject 或 DependencyProperty .感谢您在第一篇文章中的帮助。所以没有办法指定我希望我的附加属性仅适用于特定类型(此处为 FrameworkElement)?
-
啊,我应该看到的。您可以通过在 GetCollection 和 SetCollection 中使用 FrameworkElement 作为参数类型,而不是 DependencyObject 来指定该属性只能应用于 FrameworkElement。
标签: c# silverlight xaml dependency-properties windows-phone