Sceen Sceen - 23 days ago 9
C# Question

WPF Togglebutton not switching after PreviewMouseDown-Event is handled in parent control

the problem is quite simple: If you handle the PreviewMouseDown-Event of e.g. a Usercontrol and inside of the usercontrol is a togglebutton, it will not fire the build-in native checked-event and also not the clicked-event (highlighted blue). If you don't handle the preview-events it works fine.
I thought the preview events will not mark the event as handled, but even with

e.handled = false;


there will be no click or checked event afterwards.

So my question is: how can I enable the togglebutton's click and checked event?

UPDATE:

Code for understanding the problem:

WpfApplication1.cs

namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}


private void UserControl1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//working
MessageBox.Show("Preview down");
e.Handled = false; //this is what I tried
}

private void UserControl1_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
//working
MessageBox.Show("preview up");
}
}
}


WpfApplication.Xaml

<Window x:Class="WpfApplication1.MainWindow"
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"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 PreviewMouseLeftButtonDown="UserControl1_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="UserControl1_PreviewMouseLeftButtonUp" ></local:UserControl1>
</Grid>
</Window>


UserControl1.cs:

namespace WpfApplication1
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}

private void ToggleButton_Checked(object sender, RoutedEventArgs e)
{
//Not called
MessageBox.Show("test");
}

private void ToggleButton_Click(object sender, RoutedEventArgs e)
{
//not called
MessageBox.Show("test");
}
}
}


UserControl1.xaml

<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<ToggleButton Checked="ToggleButton_Checked" Click="ToggleButton_Click"></ToggleButton>
</Grid>
</UserControl>

Answer

You need to raise an event handler for the user control when an event from within the user control is fired. This will go up the chain and handle the even from both.

When clicking ToggleButton, it will fire ToggleButton_Click and it will trigger the event UserControl1_PreviousMouseLeftButtonDown.

WpfApplication1

UserControl1.ToggleButtonClick += new EventHandler(UserControl1_PreviewMouseLeftButtonDown);

private void UserControl1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    MessageBox.Show("Preview down");
    // Handle the event
}

UserControl1

public event EventHandler ToggleButtonClick;

private void ToggleButton_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("test");
    // Handle the event
}