![](/img/trans.png)
[英]How to access children in Grid with x/y coordinates instead of index?
[英]How to get a x,y coordinates of cell within a WPF grid by column and row index
我有一個網格,可以在其中添加行定義和col定義。
<Grid>
<Grid Name="layoutGrid" ></Grid>
<Canvas Name="overlayedCanvas"></Canvas>
</Grid>
。
// create rows
for (int r = 0; r < rowCount; r++)
layoutGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto});
// create columns
for (int c = 0; c < colCount; c++)
layoutGrid.ColumnDefinitions.Add(new ColumnDefinition {Width = GridLength.Auto});
然后,將我的用戶控件放在某些單元格中。 網格會根據各個用戶控件的大小自動調整大小。
我的目標是繪制一個連接某些單元格的多邊形。 例如,它可以是從單元格[1,1]的左上角開始到單元格[3,3]的右下角的Rect(1,1,3,3)。 我當時正在考慮使用這種方法通過x,y坐標訪問子級,但是我必須在每個單元格中創建虛擬控件。
然后我可以計算單元格位置:
Point topLeft = uc.TranslatePoint(new Point(0,0), layoutGrid);
Point bottomRight = uc.TranslatePoint(new Point(uc.ActualWidth, uc.ActualHeight), layoutGrid);
有更好的方法嗎?
謝謝
根據RowDefinition.ActualHeight和ColumnDefinition.ActualWidth的報告, 返回 WPF
Grid
所有單元的當前運行時尺寸。 結果以二維數組Rect[row,column]
。 例如,返回的數組中最后一個元素的Point
值Rect.BottomRight將等於調用時Grid
的RenderSize 。
public static Rect[,] GetCellRects(this Grid grid) =>
GetCellRects(grid.RowDefinitions, grid.ColumnDefinitions);
static Rect[,] GetCellRects(RowDefinitionCollection rows, ColumnDefinitionCollection cols)
{
int i = rows.Count, j = cols.Count;
var a = new Rect[i, j];
if (i > 0 && j > 0)
{
Double x;
for (i = a.GetLength(0); --i >= 0;)
for (x = rows[i].ActualHeight, j = a.GetLength(1); --j >= 0;)
a[i, j].Height = x;
for (j = a.GetLength(1); --j >= 0;)
for (x = cols[j].ActualWidth, i = a.GetLength(0); --i >= 0;)
a[i, j].Width = x;
for (i = 0; i < a.GetLength(0); i++)
for (j = 0; j < a.GetLength(1); j++)
{
if (j > 0)
a[i, j].X = a[i, j - 1].Right;
if (i > 0)
a[i, j].Y = a[i - 1, j].Bottom;
}
}
return a;
}
順便說一句,此代碼采用了經典的動態編程規范示例之一。 這樣做的好處是每個行或列(分別) 僅分別訪問一次 ActualHeight
和ActualWidth
屬性,該數目顯然很小。 嘗試設計出此處顯示的代碼的替代方案以保留該行為是一個有趣的練習。 或者說服自己,為什么最終的嵌套循環不能像以前的循環那樣反向進行?
public partial class MainWindow : Window
{
private delegate void LoadDelegate();
public MainWindow()
{
InitializeComponent();
LoadDelegate oD = Load;
Dispatcher.BeginInvoke (
oD,
System.Windows.Threading.DispatcherPriority.Loaded,
null
);
}
private void Load()
{
var items = LogicalTreeHelper
.GetChildren(uiGrid)
.OfType<Border>()
.Select(brd => new { Column = Grid.GetColumn(brd), Row = Grid.GetRow(brd), Item = brd })
.ToList();
Border oStart = items
.FirstOrDefault(item => item.Column == 1 && item.Row == 1)
.Item;
Border oStop = items
.FirstOrDefault(item => item.Column == 2 && item.Row == 2)
.Item;
Point topLeft = oStart.PointToScreen(new Point(0, 0));
Point bottomRight = oStop.PointToScreen(new Point(oStop.ActualWidth, oStop.ActualHeight));
Rectangle oRect = new Rectangle();
oRect.Fill = new SolidColorBrush(Color.FromRgb(0, 255, 0));
Point oLeft = uiCanvas.PointFromScreen(topLeft);
Canvas.SetLeft(oRect, oLeft.X);
Canvas.SetTop(oRect, oLeft.Y);
oRect.Width = bottomRight.X - topLeft.X;
oRect.Height = bottomRight.Y - topLeft.Y;
uiCanvas.Children.Add(oRect);
}
}
...
<Grid>
<Grid x:Name="uiGrid">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Background="Red" Grid.Column="1" Grid.Row="1" />
<Border Background="Red" Grid.Column="2" Grid.Row="2" />
</Grid>
<Canvas x:Name="uiCanvas" />
</Grid>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.