I am currently working on a custom Panel implementation (based on Canvas) with a specific behavior.
As I need to make several actions depending on child properties. In order to implement the control, I also developed specific child control (based on ContentControl) with some dependency properties, to set up the child option directly in the xaml.
As I also need to make verification at the AddChild call, I intercept the AddChild call by defining the [ContentProperty("NotifiableChildren")]
attribute on my Control and then make some checks before adding the child to the Canvas children.
public interface INotifiableParent
{
int AddChild(UIElement child);
void RemoveChild(UIElement child);
}
[ContentProperty("NotifiableChildren")]
public class MyPanel : Canvas, INotifiableParent
{
public MyPanel()
{
NotifiableChildren = new NotifiableUIElementCollection(this, this);
}
public NotifiableUIElementCollection NotifiableChildren { get; }
#region INotifiableParent members
public int AddChild(UIElement child)
{
// Add your custom code here
// Add the child to the InternalChildren
return this.Children.Add(child);
}
public void RemoveChild(UIElement child)
{
this.Children.Remove(child);
}
#endregion
}
It works fine, expects during the AddChild call, all my child are not completely initialized. Each instance is created and not null, but all dependency properties are not initialized (I have the same behavior with framework native controls). You can see below the corresponding xaml example with native controls.
<Window x:Class="ProtoPanel.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ProtoPanel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:MyPanel>
<Rectangle Fill="Aqua"
Width="200"
Height="100"/>
<Ellipse Fill="Bisque"
Canvas.Left="300"
Canvas.Top="150"
Height="100"
Width="100"></Ellipse>
</local:MyPanel>
</Grid>
</Window>
I put some breakpoints in my custom ContentControls and I saw that all dependency properties (Fill, Width, Heigth, ...) are initialized with xaml values after the child being added to the Canvas.
Does anyone knows if there is a way/trick to have these dep properties initialized at AddChild call ?
Thanks in advance