如何从任何LayoutControl的子项中获取ItemAdded,ItemRemoved通知?
假设我们有Grid
控件。如果我在Grid中添加新的TextBlock
控件,那么它应该通过添加的项目通知我。如果已删除,则应通知我已从Children's (UIElementCollection)
删除的项目,例如ObservableCollection
。
这可能吗?
答案 0 :(得分:6)
不确定为什么要这样做,但我想你可以扩展Grid面板并覆盖OnVisualChildrenChanged protected方法来引发一个事件:
public class ObservableGrid : Grid
{
protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
{
base.OnVisualChildrenChanged(visualAdded, visualRemoved);
if (VisualChildrenChanged != null)
VisualChildrenChanged(this, new VisualChildrenChangedEventArgs(visualAdded, visualRemoved));
}
public event EventHandler<VisualChildrenChangedEventArgs> VisualChildrenChanged;
}
public class VisualChildrenChangedEventArgs : EventArgs
{
public VisualChildrenChangedEventArgs(DependencyObject visualAdded, DependencyObject visualRemoved)
{
VisualAdded = visualAdded;
VisualRemoved = visualRemoved;
}
public DependencyObject VisualAdded { get; private set; }
public DependencyObject VisualRemoved { get; private set; }
}
答案 1 :(得分:1)
如果您能够创建自己的Panel
,则可以覆盖一些虚拟方法以在其子类中实现INotifyCollectionChanged
。但这需要您自己重新实现布局算法。
public class ObservablePanel : Panel, INotifyCollectionChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged = delegate { };
protected override UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
{
var oldObservableCollection = InternalChildren as INotifyCollectionChanged;
if (oldObservableCollection != null)
oldObservableCollection.CollectionChanged -= OnChildrenChanged;
var collection = new ObservableUIElementCollection(this, logicalParent);
collection.CollectionChanged += OnChildrenChanged;
return collection;
}
private void OnChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
{
CollectionChanged(sender, e);
}
}
public class ObservableUIElementCollection : UIElementCollection, INotifyCollectionChanged
{
public ObservableUIElementCollection(UIElement visualParent, FrameworkElement logicalParent)
: base(visualParent, logicalParent)
{
}
public event NotifyCollectionChangedEventHandler CollectionChanged = delegate { };
public override int Add(UIElement element)
{
var i = base.Add(element);
IList newItems = new List<UIElement> { element };
IList oldItems = new List<UIElement>();
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItems, oldItems));
return i;
}
...
}
如果您知道,您只使用Grid,则可以将其子类化。但我没有看到一种方法将INotifyCollectionChanged一次性添加到PresentationFramework中存在的所有面板。
答案 2 :(得分:0)
由于您正在尝试构建自己的Collection控件,因此您应该从Microsoft的ItemsControl实现中获取灵感。 您应该检查的方法是:
private void CreateItemCollectionAndGenerator()
private void OnItemCollectionChanged1(object sender, NotifyCollectionChangedEventArgs e)
internal void AdjustItemInfos(NotifyCollectionChangedEventArgs e, IEnumerable list)
这个课程通常是一个很好的研究,以最通用的方式理解实现自己的ItemsCollection的思考过程。