Sceen
Sceen

Reputation: 17

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

If you handle the PreviewMouseDown event of a UserControl and inside of the UserControl is a ToggleButton, it will not fire the built-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.

How can I enable the togglebutton's click and checked event?

Code for understanding the problem:

WpfApplication1.cs

namespace WpfApplication1
{
    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
{
    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>

Upvotes: 1

Views: 1252

Answers (1)

Hank
Hank

Reputation: 495

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
}

Upvotes: 1

Related Questions