C
C
cicatrix2021-11-12 12:27:54
WPF
cicatrix, 2021-11-12 12:27:54

WPF. Why doesn't PreviewMouseDown fire?

Good afternoon. I encountered a strange phenomenon in WPF, I can not understand what the problem is.
I have an application that draws on a DrawingVisual context. Then the picture is simply added to the Canvas, to which the PreviewMouseDown event handler is attached. I expected this event to always fire when the user clicks on the canvas, but that wasn't the case.
I prepared a minimal demonstration of the problem, I would be grateful if someone could help me figure out how to catch mouse events in this case.
To play:
1. Run
2. Click Render
3. Click on the red square - the event will not fire. Click on the green area - the event works.
Why doesn't PreviewMouseDown fire?

We have the following XAML:

<Window x:Class="MouseDownTest.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"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Click="Button_Click">Render</Button>
        <Canvas Grid.Row="1" x:Name="HostCanvas" PreviewMouseDown="HostCanvas_PreviewMouseDown" 
                Background="Green"
                Width="300" Height="300"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"/>
    </Grid>
</Window>


And the following code:
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace MouseDownTest
{
    public partial class MainWindow : Window
    {
        public class VisualHost : UIElement
        {
            public Visual Visual { get; set; }
            public VisualHost(Visual childVisual) { Visual = childVisual; }
            protected override int VisualChildrenCount => (Visual is null) ? 0 : 1;
            protected override Visual GetVisualChild(int index) { return Visual; }
        } // class VisualHost
        public MainWindow() => InitializeComponent();
        // Not FIRING inside a red square
        private void HostCanvas_PreviewMouseDown(object sender, MouseButtonEventArgs e) => MessageBox.Show("Got a click!");

        private void Render()
        {
            this.HostCanvas.Children.Clear();
            this.HostCanvas.InvalidateVisual();
            DrawingVisual vis = new();
            using (DrawingContext dc = vis.RenderOpen())
            {
                var rect = new Rect(50, 50, 50, 50);
                var redbrush = new SolidColorBrush(Colors.Red);
                var redpen = new Pen(redbrush, 2);
                dc.DrawRectangle(redbrush, redpen, rect);
            }
            var vh = new VisualHost(vis);
            this.HostCanvas.Children.Add(vh);
            System.Diagnostics.Debug.Assert(this.HostCanvas.Children.Count > 0);
        }
        private void Button_Click(object sender, RoutedEventArgs e) => Render();
    }
}


1nDbM.png

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question