Tutorial :Create a custom click event handler for a WPF usercontrol which contains a button?



Question:

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?


Solution:1

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!


Solution:2

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);  


Solution:3

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.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »