我正在尝试根据UniformGrid创建一个网格来显示每个单元格的坐标,我想在X和Y轴上显示这样的值,如下所示:
_A_ _B_ _C_ _D_
1 |___|___|___|___|
2 |___|___|___|___|
3 |___|___|___|___|
4 |___|___|___|___|
无论如何,为了做到这一点,我需要知道Uniform网格中的列数和行数,并且我尝试覆盖排列/绘图发生的3个最基本的方法,但是那里的列和行是0 ,即使我的网格中有一些控件。我可以覆盖什么方法,以便我的笛卡尔网格知道它有多少列和行?
C#:
public class CartesianGrid : UniformGrid
{
protected override Size MeasureOverride(Size constraint)
{
Size size = base.MeasureOverride(constraint);
int computedColumns = this.Columns; // always 0
int computedRows = this.Rows; // always 0
return size;
}
protected override Size ArrangeOverride(Size arrangeSize)
{
Size size = base.ArrangeOverride(arrangeSize);
int computedColumns = this.Columns; // always 0
int computedRows = this.Rows; // always 0
return size;
}
protected override void OnRender(DrawingContext dc)
{`enter code here`
int computedColumns = this.Columns; // always 0
int computedRows = this.Rows; // always 0
base.OnRender(dc);
}
}
XAML:
<local:CartesianGrid>
<Label Content="Hello" />
<Label Content="Hello" />
<Label Content="Hello" />
<Label Content="Hello" />
<Label Content="Hello" />
<Label Content="Hello" />
</local:CartesianGrid>
非常感谢任何帮助。谢谢!
答案 0 :(得分:2)
没有暴露的属性可以为您提供该信息。如果您有反射器,您可以在UpdateComputedValues
方法中查看它们所做的计算,以查找它们使用的行数和列数。
如果Rows
,Columns
和FirstColumn
为零,您可以使用类似的内容
int numVisibleChildren = this.Children.Count((c) => c.Visibility != Visibility.Collapsed);
int numColumns = (int)Math.Ceiling(Math.Sqrt(numVisibleChildren));
int numRows = (int)Math.Floor(Math.Sqrt(numVisibleChildren));
我实际上并没有运行代码,所以可能存在一些拼写错误。
答案 1 :(得分:1)
这是完整的解决方案,处理指定或不指定UniformGrid的列和行:
public class CartesianGrid : UniformGrid
{
private int _columns;
private int _rows;
private int _margin = 20;
public CartesianGrid()
{
// add some margin so the letters and numbers do show up
this.Margin = new Thickness(_margin, _margin, 0, 0);
}
protected override void OnRender(DrawingContext dc)
{
double xOffset = (this.RenderSize.Width / _columns);
double yOffset = (this.RenderSize.Height / _rows);
double xCenterOffset = xOffset / 2;
double yCenterOffset = yOffset / 2.3;
for (int i = 0; i < _columns; i++)
{
dc.DrawText(
new FormattedText((i + 1).ToString(),
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Arial"),
20,
Brushes.Black), new Point((i * xOffset) + xCenterOffset, _margin * -1));
}
for (int i = 0; i < _rows; i++)
{
dc.DrawText(
new FormattedText(((char)(i + 65)).ToString(),
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Arial"),
20,
Brushes.Black), new Point(_margin * -1, (i * yOffset) + yCenterOffset));
}
base.OnRender(dc);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
if (this.Columns != 0 && this.Rows != 0)
{
_rows = this.Rows;
_columns = this.Columns;
return base.ArrangeOverride(arrangeSize);
}
else
{
Size arrangedSize = base.ArrangeOverride(arrangeSize);
double maxChildDesiredWidth = 0.0;
double maxChildDesiredHeight = 0.0;
// Measure each child, keeping track of max desired width & height.
for (int i = 0, count = Children.Count; i < count; ++i)
{
UIElement child = Children[i];
Size childDesiredSize = child.DesiredSize;
if (maxChildDesiredWidth < childDesiredSize.Width)
{
maxChildDesiredWidth = childDesiredSize.Width;
}
if (maxChildDesiredHeight < childDesiredSize.Height)
{
maxChildDesiredHeight = childDesiredSize.Height;
}
}
if (maxChildDesiredHeight == 0 || maxChildDesiredWidth == 0)
return arrangedSize;
_columns = Convert.ToInt32(Math.Floor(this.DesiredSize.Width / maxChildDesiredWidth));
_rows = Convert.ToInt32(Math.Floor(this.DesiredSize.Height / maxChildDesiredHeight));
return arrangedSize;
}
}
}
不过,这就是我想要实现的目标:
http://wpfdude.blogspot.com/2010/06/cartesian-grid.html
谢谢!