简体   繁体   English

事件处理程序行为异常

[英]Event handlers behaving abnormally

I'm using the following WPF 我正在使用以下WPF

<Button Style="{DynamicResource NoChromeButton}" x:Name="cmdImage" Grid.Row="1" Margin="10" MouseDoubleClick="cmdImage_MouseDoubleClick" MouseDown="imgMain_MouseDown_1" MouseMove="imgMain_MouseMove_1" MouseUp="imgMain_MouseUp_1">
    <Grid x:Name="ImageGrid">
        <Image x:Name="imgMain" Panel.ZIndex="0" />
        <Button x:Name="rectBounds" Template="{StaticResource DesignerItemTemplate}" Visibility="Hidden" IsVisibleChanged="Button_IsVisibleChanged" Panel.ZIndex="1" />
    </Grid>
</Button>

The weird part is that the MouseUp , MouseDown , and MouseMove events of the outermost button don't even trigger iff the ImageSource of the Image isn't null (an image is loaded). 奇怪的是,如果ImageImageSource不为null (已加载图像),则最外面的按钮的MouseUpMouseDownMouseMove事件甚至不会触发。

I tried moving them to the Image control. 我尝试将它们移至Image控件。 They do trigger, but behave unexpectedly. 它们确实会触发,但是行为异常。

private void imgMain_MouseDown_1(object sender, MouseButtonEventArgs e)
{
    startPoint = e.GetPosition(ImageGrid);
    rect = new Rectangle
                {
                    Margin =
                        new Thickness(e.GetPosition(ImageGrid).X, e.GetPosition(ImageGrid).Y,
                                        ImageGrid.ActualWidth - e.GetPosition(ImageGrid).X,
                                        ImageGrid.ActualHeight - e.GetPosition(ImageGrid).Y),
                    Stroke = Brushes.Black,
                    StrokeThickness = 1.0
                };
    ImageGrid.Children.Add(rect);
    Panel.SetZIndex(rect, 2);
}

private void imgMain_MouseMove_1(object sender, MouseEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Released || rect == null)
        return;

    Point pos = e.GetPosition(ImageGrid);

    double x = Math.Min(pos.X, startPoint.X);
    double y = Math.Min(pos.Y, startPoint.Y);

    double w = Math.Max(pos.X, startPoint.X) - x;
    double h = Math.Max(pos.Y, startPoint.Y) - y;

    rect.Margin = new Thickness(x, y, ImageGrid.ActualWidth - x - w, ImageGrid.ActualHeight - y - h);
}

private void imgMain_MouseUp_1(object sender, MouseButtonEventArgs e)
{
    rect = null;
}

By all apparent rules, a draggable rectangle should appear, and disappear once you let go of the mouse button. 按照所有明显的规则,应该会出现一个可拖动的矩形,一旦松开鼠标按钮,该矩形就会消失。 It doesn't. 没有。 What's funny is that when I change the visibility of rectBounds , a rectangle does appear. 有趣的是,当我更改rectBounds的可见性时,确实会出现一个矩形。

There are a few things to fix here. 这里有一些要解决的问题。

First, your XAML. 首先,您的XAML。 A button inside another button? 另一个按钮中的一个按钮? I can't imagine how that should feel. 我无法想象那种感觉。 Then the ZIndex . 然后是ZIndex It's redundant since Image and Button are in the same Grid cell and the Image is declared before the Button. 这是多余的,因为Image和Button在同一个Grid单元中,并且Image在Button之前声明。 And it's also not necessary to set in on the newly created Rectangle in imgMain_MouseDown_1 . 并且也不必在imgMain_MouseDown_1新创建的RectangleimgMain_MouseDown_1

The weird part is that the MouseUp, MouseDown, and MouseMove events of the outermost button don't even trigger if the ImageSource of the Image isn't null. 奇怪的是,如果Image的ImageSource不为null,则最外面的按钮的MouseUp,MouseDown和MouseMove事件甚至不会触发。

This is exactly what you would expect, because a mouse event is only generated on those areas of a control that are actually drawn, in other words where hit testing succeeds. 这正是您所期望的,因为鼠标事件仅在控件的实际绘制区域(即命中测试成功的区域)上生成。 When there is no actual content (no image in your example), hit testing fails. 如果没有实际内容(示例中没有图像),则命中测试将失败。 You might simply assign a transparent background to the Grid to ensure that hit testing always succeeds: 您可以简单地为网格分配透明背景,以确保命中测试始终成功:

<Grid x:Name="ImageGrid" Background="Transparent">
    <Image x:Name="imgMain" />
    <Button x:Name="rectBounds" Template="{StaticResource DesignerItemTemplate}" Visibility="Hidden" IsVisibleChanged="Button_IsVisibleChanged" />
</Grid>

By all apparent rules, a draggable rectangle should appear, and disappear once you let go of the mouse button. 按照所有明显的规则,应该会出现一个可拖动的矩形,一旦松开鼠标按钮,该矩形就会消失。

No it shouldn't, unless you actually remove that Rectangle from the Grid. 不,它不应该,除非您实际上从网格中删除了该矩形。 Setting rect = null doesn't do that. 设置rect = null不会这样做。

private void imgMain_MouseUp_1(object sender, MouseButtonEventArgs e)
{
    ImageGrid.Children.Remove(rect);
    rect = null;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM