WPF 实现 ItemsControl.ItemsSourceChanged 事件的变通方法
WPF,ListBox的ItemsSource更改事件
在WPF中,一个ListBox的ItemsSource的值发生更改,这个更改事件是什么?
------解决思路----------------------
没有正式的ItemsSourceChanged事件。
你可以继承ListBox,并重载OnItemsSourceChanged方法,
或者更简单的,利用ItemsSourse是依赖属性的特点,登记你自己的改变处理:
var dpd = DependencyPropertyDescriptor.FromProperty(ListBox.ItemsSourceProperty, typeof(ListBox)); dpd.AddValueChanged(listBox1, (o, e) => { MessageBox.Show("items souce changed."); });
以下是周银辉提供的一个演示demo:
public class People : DependencyObject { public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof (string), typeof (People), new PropertyMetadata(default(string))); public string Name { get { return (string) GetValue(NameProperty); } set { SetValue(NameProperty, value); } } } //......... private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { var people = new People {Name = "zhang san"}; var descriptor = DependencyPropertyDescriptor.FromProperty(People.NameProperty, typeof (People)); descriptor.AddValueChanged(people, (o, args) => MessageBox.Show("name changed to " + people.Name)); people.Name = "Li si"; }
以下代码来自:
TypeDescriptor.GetProperties(listviewcontrol)["ItemsSource"].AddValueChanged(listviewcontrol, new EventHandler(ListView_ItemsSourceChanged));
阅读微软的源代码文档中的注释对理解 FromProperty 方法大有帮助:
/// <summary> /// Static method that returns a DependencyPropertyDescriptor from a DependencyProperty. The /// DependencyProperty may refer to either a direct or attached property. The targetType is the /// type of object to associate with the property: either the owner type for a direct property /// or the type of object to attach to for an attached property. /// </summary> internal static DependencyPropertyDescriptor FromProperty(
DependencyProperty dependencyProperty,
Type ownerType,
Type targetType,
bool ignorePropertyType)
// We have a different codepath here for attached and direct // properties. For direct properties, we route through Type // Descriptor because we need the underlying CLR property descriptor // to create our wrapped property. For attached properties, all we // need is the dp and the object type and we can create an attached // property descriptor based on that. We must special case attached // properties here because TypeDescriptor will only return attached // properties for instances, not types.
/// <summary> /// Static method that returns a DependencyPropertyDescriptor for a given property name. /// The name may refer to a direct or attached property. OwnerType is the type of /// object that owns the property definition. TargetType is the type of object you wish /// to set the property for. For direct properties, they are the same type. For attached /// properties they usually differ. /// </summary> public static DependencyPropertyDescriptor FromName(string name, Type ownerType, Type targetType, bool ignorePropertyType)
以上只是提供了变通解决方案,但是仔细思考一下:
ItemsSourceChanged 事件有存在的意义吗?
ItemsSource 依赖项属性要么为null,要么就被绑定到一个IEnumerable类型的属性;
除非手动对ItemsSource赋值(一般不会用这么笨的办法),否则,直接在绑定源的set访问器中引发ItemsSourceChanged事件(可以是CLR事件,也可以是路由事件)就行了。

浙公网安备 33010602011771号