I'd like to implement a set of similar attached behaviors for use in a WPF application. Since their all share a chunk of boilerplate code, that I don't really want to repeat for every one, I'd like to create a base behavior inherit from it. But since everything inside attached behaviors is static, I am at a loss of how to do it.
As an example, take this behavior, which executes a method on mousedown (the real behaviors would of course do something not easily done in an eventhandler):
public static class StupidBehavior
{
public static bool GetIsEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsEnabledProperty);
}
public static void SetIsEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}
// Using a DependencyProperty as the backing store for ChangeTooltip. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled", typeof(bool)开发者_JAVA技巧, typeof(StupidBehavior), new UIPropertyMetadata(false, IsEnabledChanged));
private static void IsEnabledChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
((UIElement)sender).MouseDown += { (o,e) => MyMethod(); };
}
private static void MyMethod()
{
MessageBox.Show("Boo");
}
}
Now, I'd like to create a new behavior that should have a different implementation of MyMethod, as well as a few additional properties controlling it. How should this be done?
You could create another attached property which contains the detailed implementation which is being called by the main behavior as a sub-class replacement. The object that property holds could be non-static and be used like a state-object.
(You could probably fit this into one property as well, where property == null
means off)
You could use a static constructor to form a Dictionary<DependencyProperty,EventHandler>
to map the specific DP to a specific handler and use a common DependencyPropertyChanged
callback:
static StupidBehavior()
{
handlerDictionary[IsEnabledProperty] = (o,e) => MyMethod();
handlerDictionary[SomeOtherProperty] = (o,e) => SomeOtherMethod();
}
private static void CommonPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var uie = sender as UIElement;
if (uie != null)
{
//removing before possibly adding makes sure the multicast delegate only has 1 instance of this delegate
sender.MouseDown -= handlerDictionary[args.Property];
if (args.NewValue != null)
{
sender.MouseDown += handlerDictionary[args.Property];
}
}
}
Or simply do a switch
on args.Property
. Or something in-between that involves a common method and branching based on the DependencyProperty
.
And I'm not sure why your IsEnabled
property deals with a value of type DependencyProperty
rather than something that would make more semantic sense like bool
.
精彩评论