We're writing a custom UserControl (as opposed to a lookless control) and we need to perform some initialization based on what properties our consumers set on our control in XAML.
Now in most cases, you'd use the Initialized event (or the OnInitialized override) since by the time that fires, all the XAML-set properties have been applied, but in the case of a UserControl, that isn't the case. When the Initialized event fires, all properties are still at their default values.
I didn't notice this for other controls, just UserControls, which are different in that they call InitializeComponent() in their constructor, so as a test, I commented that line out and ran the code and sure enough, this time during the Initialized event, the properties were set.
Here is some code and test results demonstrating this...
Result with InitializeComponent called in the constructor:
(Note: The values still have not been set)
TestValue (Pre-OnInitialized): Original Value
TestValue (Initialized Event): Original Value
TestValue (Post-OnInitialized): Original Value
Result with InitializeComponent completely commented out:
(Note: While the values have been set, the control isn't loaded as it needs InitializeComponent)
TestValue (Pre-OnInitialized): New Value!
TestValue (Initialized Event): New Value!
TestValue (Post-OnInitialized): New Value! // Event *was* called
and the property has been changed
All this said, what can I use to initialize my control based on user-set properties in the XAML? (Note: Loaded is too late as the control should already have been initialized by then.)
XAML Snippet
<local:TestControl TestValue="New Value!" />
TestControl.cs
public partial class TestControl : UserControl {
public TestControl() {
this.Initialized += TestControl_Initialized;
InitializeComponent();
}
protected override void OnInitialized(EventArgs e) {
Console.WriteLine("TestValue (Pre-OnInitialized): " + TestValue);
base.OnInitialized(e);
Console.WriteLine("TestValue (Post-OnInitialized): " + TestValue);
}
void TestControl_Initialized(object sender, EventArgs e) {
Console.WriteLine("TestValue (Initialized Event): " + TestValue);
}
public static readonly DependencyProperty TestValueProperty = DependencyProperty.Register(
nameof(TestValue),
typeof(string),
typeof(TestControl),
new UIPropertyMetadata("Original Value"));
public string TestValue {
get => (string)GetValue(TestValueProperty);
set => SetValue(TestValueProperty, value);
}
}