问题
I've created a custom control with, amongst others, the following:
public partial class MyButton : UserControl
{
public bool Enabled
{
get { return (bool)GetValue(EnabledProperty); }
set {
SetValue(EnabledProperty, value);
SomeOtherStuff();
}
}
}
public static readonly DependencyProperty EnabledProperty =
DependencyProperty.Register("Enabled", typeof(bool), typeof(MyButton), new PropertyMetadata(true));
public static void SetEnabled(DependencyObject obj, bool value)
{
obj.SetValue(EnabledProperty, value);
}
public static bool GetEnabled(DependencyObject obj)
{
return (bool) obj.GetValue(EnabledProperty);
}
}
In my XAML, I (try to) use binding to set the Enabled property:
<MyButton x:Name="myButtom1" Enabled="{Binding CanEnableButton}"/>
I know the bind between my control and the underlying data model is valid and working as I can bind 'IsEnabled' (a native property of the underlying UserControl) and it works as expected. However, my Enabled property is never set via the above binding. I've put breakpoints on my property set/get and they never get hit at all.
I can only imaging I've missed something relating to binding in my custom control. Can anyone see what?
I've tried implementing INotifyPropertyChanged on my control (and calling the PropertyChanged event from my Enabled setter) ... but that didn't fix it.
[ BTW: In case you are wondering "Why?": I can't intercept changes to the IsEnabled state of the base control, so I decided to implement and use my own version of a Enable/disable property (which I called Enabled) - one where I could plug my own code into the property setter ]
回答1:
First of all drop the SetEnabled
and GetEnabled
pair, these only make sense for an attached property which is not what you are doing.
Now your main problem is that you are under the false assumption that the get/set members of your propery get called during binding, they don't.
What you need is to pass a call back method in the property meta data, it's here that you intercept changes and take other actions like so:-
public bool IsEnabled
{
get { return (bool)GetValue(IsEnabledProperty); }
set { SetValue(IsEnabledProperty, value); }
}
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.Register(
"IsEnabled",
typeof(bool),
typeof(MyButton),
new PropertyMetadata(true, OnIsEnabledPropertyChanged));
private static void OnIsEnabledPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyButton source = d as MyButton;
source.SomeOtherStuff();
}
private void SomeOtherStuff()
{
// Your other stuff here
}
With this in place regardless of how the propery is changed the SomeOtherStuff
procedure will execute.
回答2:
I'd suggest using the IsEnabledChanged event which is part of every Control/UserControl.
That would allow you to hook up to the event and do whatever actions you want to take.
public MainPage()
{
InitializeComponent();
this.IsEnabledChanged += new DependencyPropertyChangedEventHandler(MainPage_IsEnabledChanged);
}
void MainPage_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
// Do SomeStuff
}
来源:https://stackoverflow.com/questions/3319527/how-to-bind-to-a-custom-property-in-a-silverlight-custom-control