views:

4412

answers:

3

Hello guys

have you ever found a problem when assigning a click event handler for your custom WPF usercontrol with a nested button control? I do.

When you put such user control in a main window, let's say Main.xaml, the MouseLeftButtonDown doesn't work, but the PreviewMouseLeftButtonDown works like a charm.

But imagine yourself telling each developer in your team to use this event when using your usercontrol... Some usercontrols in you library has MouseLeftButtonDown, others PreviewMouseLeftButtonDown.... It's a mess don't you agree?

So I've got a solution but I want someone to see if there's some elegant way to create your custom event handler called "Click".

In my usercontrol called CustomButton.xaml.cs, I have so far:

public partial class CustomButton: UserControl
{

    public CustomButton()
        : base()
 {
  this.InitializeComponent();

    }

    public delegate void ClickHandler(object sender, EventArgs e);
    public event EventHandler Click;

    public void Button_Click(object sender, RoutedEventArgs e) {//execute daddy's button click
            (((sender as Button).Parent as Grid).Parent as CustomButton).Click(sender, e);

            e.Handled = false;

    }

In my CustomButton.xaml

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="YourCompany.UI.Controls.CustomButton" d:DesignHeight="72.5" d:DesignWidth="200">
<UserControl.Resources>
blablabla
</UserControl.Resources>

<Grid x:Name="LayoutRoot">
    <Button Style="{DynamicResource CustomButton}" 
            Width="{Binding ElementName=CustomButton, Path=ActualWidth}" 
            Cursor="Hand" Foreground="#ffffff" FontSize="28" Margin="8,8,0,12" 
            HorizontalAlignment="Left" 
            Content="Custom Button" Click="Button_Click" />


</Grid>

Now in my Main.xaml, the caller, I have:

<Window x:Class="YourCompany.MyProject.Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MyProject!" Height="600" Width="800" 
MinWidth="800" MinHeight="600" WindowState="Maximized" WindowStartupLocation="CenterScreen"
xmlns:bigbola="clr-namespace:YourCompany.UI.Controls;assembly=YourCompany.UI.Controls">

<mycontrols:CustomButton Name="test" MyImage=".\Images\btnOptions.png" Cursor="Hand" 
            Texto="See options" Click="test_Click"
            Margin="168.367,176.702,253.609,0" ToolTip="See all options" Height="76.682" 
            VerticalAlignment="Top"></mycontrols:CustomButton>

Explanation:

in the usercontrol, when you click the nested button, it executes its parent custom "Click" handler.

Is there a elegant way to accomplish the same effect?

A: 

Couldn't this line:

(((sender as Button).Parent as Grid).Parent as CustomButton).Click(sender, e);

be replaced by

this.Click(sender, e);

?

Other than that though the answer depends on the exact behaviour that you want. If you want to click event of your user control to only trigger when you click on the inner button then I think you are handling it the right way. On the other hand if you want the click event to trigger whenever you click anywhere within the bounds of the user control then you are probably best styling or inheriting from the standard button control. Remember that in WPF the button's content can be any other element including another button.

Martin Harris
No, it won't work. I see your point but I have a button inside a user control, this usercontrol is a "custombutton" that has its own click event customized by me. The idea is, when you click the inner one, the outter event gets executed!
Junior Mayhé
A: 

If your implementing a button, why not just derive from button?

To answer your question though, all you need it this.

if (Click != null) Click(this, EventArgs.Empty);
mdm20
ok, but I was wondering where to attach this statement??
Junior Mayhé
A: 

Going off of what mdm20 was saying... Why are you creating a UserControl (a collection of controls grouped into 1) when you could much more easily create a CustomControl (a control that extends the functionality of an existing control, such as a Button)? Assuming a Button is the only control you'd like in CustomButton, I'd highly recommend a CustomControl over what you have (a UserControl).

Example of UserControl vs CustomControl here

Hope this helps!

Pwninstein
Yes, I was reading your comment and thinking about creating a custom control having a Button as base control. There were lots of samples showing UserControl so I started with that, using Microsoft Expression Blend to build a customized button. After I saw I wasn't able to control the click event. But later I'm going to learn how to create a simple and elegant custom button.
Junior Mayhé
Glad that helped! Good luck with your custom button :)
Pwninstein