Hi all,
A while ago I was creating a custom control in Silverlight with an enum Dependency property.
It looked like this:
- public partial class SomeCustomControl
- {
- public static readonly DependencyProperty OnOrOffDependencyProperty = DependencyProperty.Register("OnOrOff", typeof (OnOff), typeof (SomeCustomControl), new PropertyMetadata(-1, OnPropertyChangedCallback));
- public SomeCustomControl()
- {
- this.InitializeComponent();
- }
- public OnOff OnOrOff
- {
- get
- {
- return (OnOff) this.GetValue(OnOrOffDependencyProperty);
- }
- set
- {
- this.SetValue(OnOrOffDependencyProperty, value);
- }
- }
- private static void OnPropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e)
- {
- SomeCustomControl instance = (SomeCustomControl) o;
- instance.UpdateBackgroundColor((OnOff) e.NewValue);
- }
- private void UpdateBackgroundColor(OnOff newValue)
- {
- switch (newValue)
- {
- case OnOff.On:
- this.Rectangle.Fill = new SolidColorBrush(Colors.Green);
- break;
- case OnOff.Off:
- this.Rectangle.Fill = new SolidColorBrush(Colors.Red);
- break;
- }
- }
- }
The enum itself was quite simple:
- public enum OnOff
- {
- On,
- Off
- }
The control just changes background color when you set the enum to On (green), or Off (red). Very simple.
The problem is that the dependency property will take the enum member with number 0 as default, OnOff.On that is. And when setting the value in XAML (or code for that matter) will not update the property backing the dependency property:
The code to render this is found here:
- <EnumProblem:SomeCustomControl OnOrOff="On"
- Grid.Row="1">
- </EnumProblem:SomeCustomControl>
- <EnumProblem:SomeCustomControl OnOrOff="Off"
- Grid.Row="1"
- Grid.Column="1">
As you can see the left one is NOT green.
This is because the default is OnOff.On (value 0), and setting it (again) to On doesn’t trigger the execution of OnPropertyChangedCallback.
We can solve this (of course, otherwise what would be the point of writing this?
)
The first solution you might think about is setting the default value of the Dependency Property’s default value. Maybe –1 for example, so that at least the engine can detect a change.
- public static readonly DependencyProperty OnOrOffDependencyProperty = DependencyProperty.Register("OnOrOff", typeof (OnOff), typeof (SomeCustomControl), new PropertyMetadata(-1, OnPropertyChangedCallback));
Running the app like this will cause an exception, since it cannot convert the –1 to the OnOff enum.
The other solution is setting the value of the first member to a positive value, which makes the code work:
- public enum OnOff
- {
- On = 1,
- Off
- }
Now you might think: What’s the difference, the first time it tries to convert –1 to OnOff, and the second time it tried to convert 0 to OnOff, and it both cases it the value doesn’t exist in the enum.
The reason here is that you can have an enum that starts at 1, but you can still set create an instance of that enum with a value of 0.
But creating the enum with a value of –1 doesn’t work:
This is why setting –1 to the default value of the dependency property doesn’t work (unless you of course have a –1 value in the enum!)
If you want the source, and you know a good place to upload it, please mail me