簡體   English   中英

檢測按鈕是否在繪制的矩形框內

[英]Detect if buttons are inside drawn rect box

我有一個帶有矩形框的畫布,用於選擇框和我的統一網格,其中包含我動態生成的按鈕。

選取框選擇工具現在正在運行,即我可以看到它被繪制在統一網格上,並且根據示例代碼,這里有mousedown位置和mouseup位置:

在WPF中單擊並拖動選擇框

我的XAML是這樣的:

<Grid Name="mainGrid" DockPanel.Dock="Top"  Width="800" Height="400">
    <Rectangle x:Name="selectionBox" Visibility="Collapsed" Stroke="White" StrokeThickness="4" StrokeDashArray="2,1"/>
    <UniformGrid DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="uniformGrid" Grid.Row="1" Width="{Binding Width, ElementName=mainGrid}" Height="{Binding Height, ElementName=mainGrid}"
Rows="{Binding RowCount}"
Columns="{Binding ColumnCount}" MouseDown="UniformGrid_MouseDown" MouseUp="UniformGrid_MouseUp" MouseMove="UniformGrid_MouseMove" Background="Transparent">
    </UniformGrid>
    <Canvas Name="buttonCanvas">
    </Canvas>
</Grid>

問題是,我不確定如何檢查我的按鈕(UniformGrid的子代)是否包含在/部分包含在此矩形中。

這是您鏈接的解決方案的擴展。

以下是一種確定給定按鈕在給定MouseUpMouseDown位置內的方法。 在該示例中,有一個名為mouseDownPos的成員變量和一個名為mouseUpPos的局部變量,該變量注冊了每個變量。 因此,在Grid_MouseUp事件處理程序中,我將添加以下代碼以獲取Canvas所有Button控件,對其進行迭代,然后將它們傳遞給方法以查看其是否在上述區域內。

private void Grid_MouseUp(object sender, MouseButtonEventArgs e)
{
    // Release the mouse capture and stop tracking it.
    mouseDown = false;
    theGrid.ReleaseMouseCapture();

    // Hide the drag selection box.
    selectionBox.Visibility = Visibility.Collapsed;

    Point mouseUpPos = e.GetPosition(theGrid);

    // TODO: 
    //
    // The mouse has been released, check to see if any of the items 
    // in the other canvas are contained within mouseDownPos and 
    // mouseUpPos, for any that are, select them!
    //
    var buttons = canvasButtons.Children.OfType<System.Windows.Controls.Button>();

    foreach (var button in buttons)
    {
        var isInSelection = IsInsideSelection(mouseDownPos, mouseUpPos, button);
    }
}

IsInsideSelection()是我編寫的函數,它要求鼠標在矩形的上下位置以及Button控件。

private bool IsInsideSelection(Point mouseDown, Point mouseUp, System.Windows.Controls.Button button)
{
    // This grabs the coordinates of the button, relative to the main window. 
    // If you would like it relative to something else, like your canvas or the grid, you'd have to pass appropriate control to the `TransformToAncestor()` function.
    var buttonPos = button.TransformToAncestor(mainWin).Transform(new Point(0, 0));

    // Bottom right corner coordinates of the button control.
    var btnBottomRight = new Point(buttonPos.X + button.Width, buttonPos.Y + button.Height);

    // If button X and Y (which is the top left corner of the button) 
    // are outside the mouse down position, it's not inside the rectangle 
    if (buttonPos.X < mouseDown.X || buttonPos.Y < mouseDown.Y)
        return false;

    // If X and Y of button bottom right corner is outside mouse up coordinates,
    // then the control is again outside the rectangle
    if (btnBottomRight.X > mouseUp.X || btnBottomRight.Y > mouseUp.Y)
        return false;

    // Everything else, control is inside
    return true;
}

注意:

  • 這將獲取按鈕相對於主窗口的坐標。 如果您希望相對於畫布或網格之類的其他東西,則必須將適當的控件傳遞給TransformToAncestor()函數。

編輯

僅當矩形從左到右繪制時,以上功能才有效。 要處理從右到左的情況,可以上下移動鼠標,如下所示:

private bool IsInsideSelection(Point mouseDown, Point mouseUp, System.Windows.Controls.Button button)
{
    if (mouseUp.X < mouseDown.X)
    {
        var temp = mouseUp;
        mouseUp = mouseDown;
        mouseDown = temp;
    }

    var buttonPos = button.TransformToAncestor(mainWin).Transform(new Point(0, 0));
    var btnBottomRight = new Point(buttonPos.X + button.Width, buttonPos.Y + button.Height);

    if (buttonPos.X < mouseDown.X || buttonPos.Y < mouseDown.Y)
        return false;

    if (btnBottomRight.X > mouseUp.X || btnBottomRight.Y > mouseUp.Y)
        return false;

    return true;
}

編輯2:

以下是我的測試應用程序的XAML ,我正在使用UniformGrid在此處保存控件。 請注意,在檢索按鈕時,必須使用UniformGrid的名稱(在這種情況下為'unfGrid`)。

<Window ...
        Name="mainWin"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="600" Width="600">
    <Grid x:Name="theGrid"
          MouseDown="Grid_MouseDown"
          MouseUp="Grid_MouseUp"
          MouseMove="Grid_MouseMove"
          Background="Transparent">
        <UniformGrid Name="unfGrid" Grid.Row="0">
            <Button Name="Btn1" Content="Button1" Grid.Row="0"
                        Width="100" Height="24"/>
            <Button Name="Btn2" Content="Button2" Grid.Row="1"
                        Width="100" Height="24"/>
            <Button Name="Btn3" Content="Button3" Grid.Row="2"
                        Width="100" Height="24"/>
            <!-- This canvas contains elements that are to be selected -->
        </UniformGrid>

        <Canvas Grid.Row="0">
            <!-- This canvas is overlaid over the previous canvas and is used to 
            place the rectangle that implements the drag selection box. -->
            <Rectangle
                x:Name="selectionBox"
                Visibility="Collapsed"
                Stroke="Black"
                StrokeThickness="1"/>
        </Canvas>
    </Grid>
</Window>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM