Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Okay, long time ago but here is the solution I found that time back...</p> <p><strong>The Collection:</strong> Note the hack comments.</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Media; using System.Collections.ObjectModel; using WPF.Controls.Primitives; namespace WPF.Controls.Core { public class PrimitiveCollection : ObservableCollection&lt;Primitive&gt; { protected PrimitiveContainerVisual _owner; public PrimitiveCollection(PrimitiveContainerVisual owner) : base() { if (owner == null) throw new ArgumentNullException("owner"); _owner = owner; } protected override void ClearItems() { foreach (var item in this) { item.IsDirtyChanged -= new IsDirtyChangedHandler(item_IsDirtyChanged); _owner.InternalRemoveVisualChild(item); } base.ClearItems(); } protected override void InsertItem(int index, Primitive item) { if (item != null &amp;&amp; item.Parent != null) throw new ArgumentNullException("Visual has parent"); item.IsDirtyChanged += new IsDirtyChangedHandler(item_IsDirtyChanged); _owner.InternalAddVisualChild(item); base.InsertItem(index, item); } protected override void RemoveItem(int index) { Primitive item = this[index]; item.IsDirtyChanged -= new IsDirtyChangedHandler(item_IsDirtyChanged); _owner.InternalRemoveVisualChild(item); base.RemoveItem(index); } protected override void OnPropertyChanged(System.ComponentModel.PropertyChangedEventArgs e) { base.OnPropertyChanged(e); } void item_IsDirtyChanged(object sender, PrimitiveChangedEventArgs e) { if(e.IsDirty) _owner.RequestRedraw(); } } } </code></pre> <p><strong>And the Control which you can use in XAML</strong></p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Media; using WPF.Controls.Primitives; using System.Windows; using System.Reflection; namespace WPF.Controls.Core { public class PrimitiveContainerVisual : Visual { private PrimitiveCollection _primitives; private PropertyInfo _contentBoundsPropInfo; private PropertyInfo _descendantBoundsPropInfo; public PrimitiveCollection Children { get { return _primitives; } set { _primitives = value; } } public Rect ContentBounds { // HACK access internal property of Visual get { return (Rect)_contentBoundsPropInfo.GetValue(this, null); } } public Rect DescendantBounds { // HACK access internal property of Visual get { return (Rect)_descendantBoundsPropInfo.GetValue(this, null); } } public PrimitiveContainerVisual() { _primitives = new PrimitiveCollection(this); Type thisType = this.GetType(); BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance; _contentBoundsPropInfo = thisType.GetProperty("VisualContentBounds", flags); _descendantBoundsPropInfo = thisType.GetProperty("VisualDescendantBounds", flags); } internal void InternalAddVisualChild(Primitive prim) { this.AddVisualChild(prim); } internal void InternalRemoveVisualChild(Primitive prim) { this.RemoveVisualChild(prim); } public bool RequestRedraw() { UIElement uiParent = VisualParent as UIElement; if (uiParent != null) { uiParent.InvalidateVisual(); return true; } else return false; } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload