Wpf 统一网格行和列
我试图基于UniformGrid创建一个网格来显示每个单元格的坐标,我想显示X轴和Y轴上的值,如下所示:Wpf 统一网格行和列,wpf,Wpf,我试图基于UniformGrid创建一个网格来显示每个单元格的坐标,我想显示X轴和Y轴上的值,如下所示: _A_ _B_ _C_ _D_ 1 |___|___|___|___| 2 |___|___|___|___| 3 |___|___|___|___| 4 |___|___|___|___| 无论如何,为了做到这一点,我需要知道统一网格中的列数和行数,并且我尝试覆盖3种最基本的方法,其中排列/绘制发生,但其中的列数和行数为0,即使我的网格中有一些控件。我可以重写什么方法使笛卡尔网格知
_A_ _B_ _C_ _D_
1 |___|___|___|___|
2 |___|___|___|___|
3 |___|___|___|___|
4 |___|___|___|___|
无论如何,为了做到这一点,我需要知道统一网格中的列数和行数,并且我尝试覆盖3种最基本的方法,其中排列/绘制发生,但其中的列数和行数为0,即使我的网格中有一些控件。我可以重写什么方法使笛卡尔网格知道它有多少列和行
C#:
XAML:
非常感谢您的帮助。谢谢 没有公开的属性提供这些信息。如果您有reflector,您可以在
updateComputerdValues
方法中查看它们所做的计算,以找到它们使用的行数和列数
如果行
、列
和第一列
为零,则可以使用类似的方法
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));
我还没有实际运行代码,因此可能有一些输入错误。以下是完整的解决方案,用于指定或不指定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;
}
}
}
公共类CartesianGrid:UniformGrid
{
专用int_列;
私有整数行;
私人内部利润率=20;
公共CartesianGrid()
{
//添加一些边距,使字母和数字显示出来
此.Margin=新厚度(_-Margin,_-Margin,0,0);
}
受保护的覆盖无效OnRender(DrawingContext dc)
{
double xOffset=(this.RenderSize.Width/_列);
double yOffset=(this.RenderSize.Height/_行);
双xCenterOffset=xOffset/2;
双Y中心偏移=Y偏移/2.3;
对于(int i=0;i<\u列;i++)
{
dc.DrawText(
新的格式化文本((i+1).ToString(),
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
新字体(“Arial”),
20,
黑色),新点((i*xOffset)+xCenterOffset,_margin*-1));
}
对于(int i=0;i<\u行;i++)
{
dc.DrawText(
新的格式化文本(((char)(i+65)).ToString(),
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
新字体(“Arial”),
20,
画笔。黑色),新点(_margin*-1,(i*yOffset)+yCenterOffset));
}
base.OnRender(dc);
}
受保护的替代尺寸ArrangeOverride(尺寸arrangeSize)
{
if(this.Columns!=0&&this.Rows!=0)
{
_rows=this.rows;
_columns=this.columns;
返回base.ArrangeOverride(arrangeSize);
}
其他的
{
大小arrangedSize=base.ArrangeOverride(arrangeSize);
双maxChildDesiredWidth=0.0;
双maxChildDesiredHeight=0.0;
//测量每个孩子,跟踪所需的最大宽度和高度。
for(int i=0,count=Children.count;i
顺便说一句,这就是我想要实现的目标:
谢谢 哇,你的解决方案真的很简单,只是我不得不改变numRows来使用数学。天花板也一样。我自己提出了另一个解决方案,但我更喜欢你的(在问题中发布了我的解决方案)。谢谢很抱歉,您的解决方案不起作用,尽管要简单得多。在我们的例子中,列数和行数是不同的。因此,我必须使用我的解决方案来计算列和行的实际数量,而不假设这些数字是相同的。谢谢实际上nvm,从一开始就比较容易,在我们的项目中,列和行是通过DependencyProperty专门设置的,当列和行没有设置时,您的解决方案应该可以很好地工作,这正是我最初的目标。谢谢
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));
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;
}
}
}