Update: this blog has been moved to http://brandonzeider.me/2010/microsoft-net/silverlight-default-button-behavior/
The ASP .NET Panel exposes a great property called DefaultButton. This allows you to specify the ID of the button that will be clicked when the user presses the Enter key. If you've ever wanted similar functionality in Silverlight, you can do this with Behaviors. A behavior allows you extend functionality of DependencyObjects.
namespace System.Windows.Interactivity
{
public abstract class Behavior : Behavior where T : global::System.Windows.DependencyObject
{
protected Behavior();
protected T AssociatedObject { get; }
}
}
Behavior (definition above) is an abstract class defined in the System.Windows.Interactivity namespace that you can extend to build your own custom functionality, like a default button. System.Windows.Interactivity is an assembly shipped with Microsoft Blend. Even if you don't use Microsoft Blend, you can still reference this assembly in your Silverlight project. If you do not have Blend installed, you have to remember to set the CopyLocal property to true on the assembly reference, as the assembly is not in the Global Assembly Cache (GAC).
For this example, I will create a default button behavior to be used with a UserControl. To make default button functionality work, we need to handle the KeyDown event of the UserControl.
protected override void OnAttached()
{
AssociatedObject.KeyDown += DefaultButtonBehaviorKeyDown;
}
protected override void OnDetaching()
{
AssociatedObject.KeyDown -= DefaultButtonBehaviorKeyDown;
}
There we can check the key pressed to determine if it was the Enter key. If so, we need a way to invoke the Command associated with that Button. We can do this by using a ButtonAutomationPeer. ButtonAutomationPeer is part of the UI Automation exposed by Silverlight.
From MSDN:
UI Automation provides programmatic access to most user interface (UI) elements on the desktop, enabling assistive technology products such as screen readers to provide information about the UI to end users and to manipulate the UI by means other than standard input. UI Automation also allows automated test scripts to interact with the UI.
We can then create an object of type IInvokeProvider to invoke the button's command.
private void DefaultButtonBehaviorKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter && !string.IsNullOrEmpty(DefaultButtonName))
{
UserControl view = sender as UserControl;
if (view != null)
{
Button button = view.FindName(DefaultButtonName) as Button;
if (button != null && button.IsEnabled)
{
ButtonAutomationPeer peer = new ButtonAutomationPeer(button);
IInvokeProvider invokeProvider = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
if (invokeProvider != null)
{
invokeProvider.Invoke();
}
}
}
}
}
Now we are ready to wire it up within our view. First we define the XML namespaces for System.Windows.Interactivity and our behavior:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:behaviors="clr-namespace:Framework.Behaviors;assembly=Framework"
Next we define our behavior for the UserControl:
<i:Interaction.Behaviors>
<behaviors:DefaultButtonBehavior DefaultButtonName="SubmitButton"/>
</i:Interaction.Behaviors>
That's it. You now have a reusable behavior that will reliably inovke a button's command that can be defined in XAML. For a working example, see the link below.
DefaultButtonExample.zip (182.66 kb)

This work is licensed under a Creative Commons Attribution 3.0 Unported License.
Tags: .NET,
Silverlight,
ASP .NET
Categories: Microsoft .NET |
Silverlight