事件处理程序行为异常

本文关键字:异常 程序 事件处理 | 更新日期: 2023-09-27 17:52:52

我正在使用以下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>

奇怪的是,最外层按钮的MouseUp, MouseDownMouseMove事件甚至不会触发ImageImageSource不是null(加载图像)。

我试着将它们移动到Image控件。它们确实会触发,但行为出乎意料。

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

根据所有明显的规则,应该出现一个可拖动的矩形,一旦松开鼠标按钮就会消失。它不是。有趣的是,当我改变rectBounds的可见度时,一个矩形出现了。

事件处理程序行为异常

这里有一些事情需要修复。

首先是XAML。一个扣子套在另一个扣子里?我无法想象那是什么感觉。然后是ZIndex。这是多余的,因为图像和按钮在同一个网格单元格中,并且图像在按钮之前声明。也没有必要在imgMain_MouseDown_1中设置新创建的Rectangle

的MouseUp, MouseDown和MouseMove事件的ImageSource时,最外层的按钮甚至不会触发图片不为空

这正是您所期望的,因为鼠标事件只在控件实际绘制的那些区域生成,换句话说,命中测试成功。如果没有实际内容(示例中没有图像),命中测试将失败。您可以简单地为网格分配一个透明的背景,以确保命中测试总是成功的:

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

根据所有明显的规则,应该出现一个可拖动的矩形,并且松开鼠标按钮就会消失。

不,它不应该,除非你真的从网格中移除那个矩形。设置rect = null不会这样做。

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