Wednesday, November 19, 2008

Silverlight 2: Getting button positions on clicks

For whatever reason, In Beta 2 of Silverlight 2 Microsoft decided to remove support for the MouseLeftButtonDown event on Buttons. The argument was the functionality of MouseLeftButtonDown was already in the Click event, so they got rid of it. But there is one major difference: the event args of Click are RoutedEventArgs, while for MouseLeftButtonDown the args are MouseButtonEventArgs.

For my purposes, the problem was that I needed access to the mouse position. In my Silverlight 2 app, I’m displaying a popup usercontrol whose position is relative to where it was clicked. It’ll draw a bit to the side with additional information on a DataGrid row.

After some experimentation and frustration, I’ve implemented a solution: simply extend the Button class and override the OnMouseButtonLeftDown event, and have it set Handled to “false”. Quite simply, this code re-wires the event for Button like it should have to begin with:
public class PositionButton : Button
{
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
e.Handled = false;
}

protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
e.Handled = false;
}
}


Then at the top of your XAML, add in the reference to your custom UserControl namespace.

<UserControl …xmlns:uc="clr-namespace:YourNamespace.UserControls">


When you reference the button, instead of using <Button> use <uc:PositionButton>, like so:

<hc:PositionButton x:Name="btnViewComments" MouseLeftButtonDown="clickComments"...>

Then in your code behind, you can simply reference the Position:

private void clickComments(object sender, MouseButtonEventArgs e)
{
Point pos = e.GetPosition(App.Current.RootVisual);
// do whatever you want with the position
}

No comments:

Post a Comment