0

I have a problem with a PreviewMouseDown event. I have an app that does some complex drawing in a DrawingVisual which is later added on the canvas. I've made a minimal working demonstration of the problem. Steps to reproduce:

  1. Run an app
  2. Click Render
  3. Click inside a red area. PreviewMouseDown event on the Canvas is firing on the green area but doesn't fire at the red one. I really need to capture the mouse events inside this red area. How can this be accomplished?

Here the 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 here is the code behind:

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

So, how can I capture the mouse inside a red area and why exactly PreviewMouseDown is not firing?

PreviewMouseDown not firing inside a red area

cicatrix
  • 163
  • 1
  • 10

0 Answers0