简体   繁体   中英

Event handlers behaving abnormally

I'm using the following 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).

I tried moving them to the Image control. 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.

There are a few things to fix here.

First, your XAML. A button inside another button? I can't imagine how that should feel. Then the ZIndex . It's redundant since Image and Button are in the same Grid cell and the Image is declared before the Button. And it's also not necessary to set in on the newly created Rectangle in imgMain_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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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