Procedura: eseguire l'override dell'albero logico
Benché non sia necessario nella maggior parte dei casi, gli autori di controlli avanzati possono eseguire l'override dell'albero logico.
Esempio
In questo esempio viene descritto come creare una sottoclasse di StackPanel per eseguire l'override dell'albero logico, in questo caso per imporre un comportamento per il quale un pannello può disporre e può eseguire il rendering di un solo elemento figlio. Benché non si tratta necessariamente di un comportamento utile, viene presentato come mezzo per illustrare lo scenario di override dell'albero logico normale di un elemento.
Public Class SingletonPanel
Inherits StackPanel
'Private _children As UIElementCollection
Private _child As FrameworkElement
Public Sub New()
End Sub
Public Property SingleChild() As FrameworkElement
Get
Return _child
End Get
Set(ByVal value As FrameworkElement)
If value Is Nothing Then
RemoveLogicalChild(_child)
Else
If _child Is Nothing Then
_child = value
Else
' raise an exception?
MessageBox.Show("Needs to be a single element")
End If
End If
End Set
End Property
Public Sub SetSingleChild(ByVal child As Object)
Me.AddLogicalChild(child)
End Sub
Public Shadows Sub AddLogicalChild(ByVal child As Object)
_child = CType(child, FrameworkElement)
If Me.Children.Count = 1 Then
Me.RemoveLogicalChild(Me.Children(0))
Me.Children.Add(CType(child, UIElement))
Else
Me.Children.Add(CType(child, UIElement))
End If
End Sub
Public Shadows Sub RemoveLogicalChild(ByVal child As Object)
_child = Nothing
Me.Children.Clear()
End Sub
Protected Overrides ReadOnly Property LogicalChildren() As IEnumerator
Get
' cheat, make a list with one member and return the enumerator
Dim _list As New ArrayList()
_list.Add(_child)
Return CType(_list.GetEnumerator(), IEnumerator)
End Get
End Property
End Class
public class SingletonPanel : StackPanel
{
//private UIElementCollection _children;
private FrameworkElement _child;
public SingletonPanel() {
}
public FrameworkElement SingleChild
{
get { return _child;}
set
{
if (value==null) {
RemoveLogicalChild(_child);
} else {
if (_child==null) {
_child = value;
} else {
// raise an exception?
MessageBox.Show("Needs to be a single element");
}
}
}
}
public void SetSingleChild(object child)
{
this.AddLogicalChild(child);
}
public new void AddLogicalChild(object child)
{
_child = (FrameworkElement)child;
if (this.Children.Count == 1)
{
this.RemoveLogicalChild(this.Children[0]);
this.Children.Add((UIElement)child);
}
else
{
this.Children.Add((UIElement)child);
}
}
public new void RemoveLogicalChild(object child)
{
_child = null;
this.Children.Clear();
}
protected override IEnumerator LogicalChildren
{
get {
// cheat, make a list with one member and return the enumerator
ArrayList _list = new ArrayList();
_list.Add(_child);
return (IEnumerator) _list.GetEnumerator();}
}
}
Per ulteriori informazioni sull'albero logico, vedere Strutture ad albero in WPF.