我現在真的很絕望。我只是無法更進一步,原則上它不應該那么困難。我嘗試在過去 2 周內解決它。以下任務/問題:我的 C# WPF 專案中有一個名為“MarkPointsMap”的畫布,上面有不同型別的標記點(3 種不同顏色的矩形)。一個 MarkPointsMap 可以在整個 MarkPointsMap 中包含大約 3000-4000 個不同的 MarkPoints(該畫布的子項)。MarkPoints 的位置從 .tab 檔案中加載,該檔案被轉換為名為“MarkPoints”的串列,并在加載相應的 .tab 檔案后作為子項添加到“MarkPointsMap”畫布上。
這是 MarkPointsMap 的螢屏截圖:

例如,大部分是小矩形(綠色的),一些中間的矩形(黃色的)和兩個大的矩形(紅色的)。應使用選擇矩形選擇多個標記點。在我的專案中,我已經可以繪制選擇矩形,但是“if this.selectRect.Contains(MarkPointsMap.Children)”(見下文)部分不起作用。
選擇矩形如下所示:

在程式中加載 .tab 檔案后呼叫的以下方法“drawMarkPoints”在畫布“MarkPointsMap”上繪制標記點:
public void drawMarkPoints()
{
MarkPointsMap.Children.Clear();
foreach (MarkPoint markpoint in this.Marks.markpoints)
{
if (markpoint.type.relevant)
{
Rectangle markpointArea = new Rectangle();
markpointArea.Tag = markpoint;
//!!
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
mySolidColorBrush.Color = markpoint.fillColor;
markpointArea.Fill = mySolidColorBrush;
markpointArea.StrokeThickness = 0.2;
markpointArea.Stroke = Brushes.Black;
markpointArea.Width = markpoint.symbol.Width;
markpointArea.Height = markpoint.symbol.Height;
//set the markpoints in canvas
Canvas.SetLeft(markpointArea, getCanvasCoordinates(markpoint.center).X - 0.5 * markpoint.symbol.Width);
Canvas.SetTop(markpointArea, getCanvasCoordinates(markpoint.center).Y - 0.5 * markpoint.symbol.Height);
MarkPointsMap.Children.Add(markpointArea);
}
}
}
選擇矩形使用三個滑鼠事件(MarkPointsMap_MouseDown、MarkPointsMap_MouseMove、MarkPointsMap_MouseUp)在畫布“MarkPointsMap”中繪制:
public Rect itemRect;
public Rect selectRect;
private point anchorPoint;
private Rectangle manualDragRect = new Rectangle();
private void MarkPointsMap_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
isLeftMouseButtonDownOnWindow = true;
anchorPoint = e.MouseDevice.GetPosition(MarkPointsMap);
MarkPointsMap.CaptureMouse();
e.Handled = true;
manualDragRect = new Rectangle
{
Stroke = Brushes.Red,
StrokeThickness = 2
};
MarkPointsMap.Children.Add(manualDragRect);
}
}
private void MarkPointsMap_MouseMove(object sender, MouseEventArgs e)
{
if (!MarkPointsMap.IsMouseCaptured)
return;
Point location = e.MouseDevice.GetPosition(MarkPointsMap);
double minX = Math.Min(location.X, anchorPoint.X);
double minY = Math.Min(location.Y, anchorPoint.Y);
double maxX = Math.Max(location.X, anchorPoint.X);
double maxY = Math.Max(location.Y, anchorPoint.Y);
Canvas.SetTop(manualDragRect, minY);
Canvas.SetLeft(manualDragRect, minX);
double height = maxY - minY;
double width = maxX - minX;
manualDragRect.Height = Math.Abs(height);
manualDragRect.Width = Math.Abs(width);
Point xy_2 = new Point((Canvas.GetLeft(manualDragRect) 0.5 * width), (Canvas.GetTop(manualDragRect) 0.5 * height));
this.selectRect = new Rect(xy_2.X, xy_2.Y, width, height);
}
private void MarkPointsMap _MouseUp(object sender, MouseButtonEventArgs e)
{
MarkPointsMap.ReleaseMouseCapture();
foreach (MarkPoint markpoint in this.Marks.markpoints)
{
Rect itemRect = new Rect(markpoint.center.X, markpoint.center.Y, markpoint.symbol.Width, markpoint.symbol.Height);
if (selectRect.Contains(itemRect))
{
MessageBox.Show("Test!"); // it does not reach this code, if I circle several markpoints with the red selection-rectangle called “selectRect”
}
}
}
為什么這不起作用?我想這與從矩形(使用 derictive 的 System.Windows.Shapes)到 struct Rect 的轉換有關:IFormattable。未達到的“if (selectRect.Contains(itemRect)”應在透視圖中將選擇矩形內的所有標記點著色為紅色,然后計算中間的點 (x-Coordinate, y-Coordinate) -選擇矩形的點并將這個中間點添加回原始 .tab 檔案。
任何想法或提示,我該如何繼續?提前謝謝。最好的問候!
uj5u.com熱心網友回復:
看來你的計算是錯誤的。您正在抵消selectRect. 您將其相對于渲染的manualDragRect. 這樣,您測驗的區域與您通過呈現的選擇范圍定義的區域完全不同。
此外,您正在捕獲滑鼠,Canvas但在某些不同的控制元件上釋放捕獲。它也應該發布MarkPointsMap。還要小心將滑鼠事件標記為已處理。如果輸入處理不是自定義控制元件的一部分,您通常應該避免使用它。
您應該考慮將 anItemsControl與Canvasas 面板一起使用。然后,您可以將繪圖移動到標記并DataTemplate為MarkPoint資料定義 a。
我建議使用從形狀Rect回傳的原件。manualDragRect這意味著您應該洗掉selectRect欄位和相關計算:
private void MarkPointsMap_MouseUp(object sender, MouseButtonEventArgs e)
{
MarkPointsMap.ReleaseMouseCapture();
foreach (MarkPoint markpoint in this.Marks.markpoints)
{
Rect itemRect = new Rect(markpoint.center.X, markpoint.center.Y, markpoint.symbol.Width, markpoint.symbol.Height);
Rect selectionBounds = manualDragRect.RenderedGeometry.Bounds;
selectionBounds.Offset(Canvas.GetLeft(manualDragRect), Canvas.GetTop(manualDragRect));
if (selectionBounds.Contains(itemRect))
{
MessageBox.Show("Test!");
}
// TODO::Calculate center of selectionBounds
Point selectionBoundsCenter = ...;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/415529.html
標籤:
上一篇:wpfdatacontext中的{binding}和繼承有什么區別?
下一篇:C#WPF錯誤:System.Windows.Markup.XamlParseException:“無法從文本“Hyperlink_RequestNavigate”創建“RequestNavigate
