[英]Detect if buttons are inside drawn rect box
我有一個帶有矩形框的畫布,用於選擇框和我的統一網格,其中包含我動態生成的按鈕。
選取框選擇工具現在正在運行,即我可以看到它被繪制在統一網格上,並且根據示例代碼,這里有mousedown位置和mouseup位置:
我的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的子代)是否包含在/部分包含在此矩形中。
這是您鏈接的解決方案的擴展。
以下是一種確定給定按鈕在給定MouseUp
和MouseDown
位置內的方法。 在該示例中,有一個名為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;
}
以下是我的測試應用程序的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.