WPF:在用户绘制的控件中显示二维数组的正确方法是什么
我想制作一个用户绘制的控件,其唯一目的是显示 Color[,] 数组。控件本身应该绘制一个由相应颜色的矩形组成的 NxM 网格。
我试图从 FrameworkElement 继承并重写 OnRender 方法:
public class CustomControl1 : FrameworkElement
{
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
}
public Color[,] ColorCollection
{
get { return (Color[,])GetValue(ColorGridProperty); }
set { SetValue(ColorGridProperty, value); }
}
public static readonly DependencyProperty ColorGridProperty =
DependencyProperty.Register("ColorCollection", typeof(Color[,]), typeof(CustomControl1),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
protected override void OnRender(DrawingContext drawingContext)
{
if (ColorCollection != null)
{
int dimx = this.ColorCollection.GetLength(0);
int dimy = this.ColorCollection.GetLength(1);
double w = this.ActualWidth / dimx;
double h = this.ActualWidth / dimy;
for (int x = 0; x < dimx; x++)
{
for (int y = 0; y < dimy; y++)
{
SolidColorBrush brush = new SolidColorBrush(ColorCollection[x, y]);
drawingContext.DrawRectangle(brush, null, new Rect(x * w, 0, w, this.ActualHeight));
}
}
}
}
}
问题是当我更改底层数组中的元素时,我的控件不会重新绘制自身。当我分配一个全新的数组或调整控件的大小时,它工作得很好。
显然我需要另一个类以某种方式通知控制集合中的内部更改。我正在查看 INotifyCollectionChange 和 ObservableCollection,但我发现的唯一文章是关于将集合绑定到现有控件,而不是自定义用户绘制的控件。所以我在这一点上感到困惑和困惑。
I want to make a user-drawn control for the only purpose of displaying a Color[,] array. The control itself should draw an NxM grid of rectangles of corresponding colors.
I'm trying to inherit from a FrameworkElement and to override OnRender method:
public class CustomControl1 : FrameworkElement
{
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
}
public Color[,] ColorCollection
{
get { return (Color[,])GetValue(ColorGridProperty); }
set { SetValue(ColorGridProperty, value); }
}
public static readonly DependencyProperty ColorGridProperty =
DependencyProperty.Register("ColorCollection", typeof(Color[,]), typeof(CustomControl1),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
protected override void OnRender(DrawingContext drawingContext)
{
if (ColorCollection != null)
{
int dimx = this.ColorCollection.GetLength(0);
int dimy = this.ColorCollection.GetLength(1);
double w = this.ActualWidth / dimx;
double h = this.ActualWidth / dimy;
for (int x = 0; x < dimx; x++)
{
for (int y = 0; y < dimy; y++)
{
SolidColorBrush brush = new SolidColorBrush(ColorCollection[x, y]);
drawingContext.DrawRectangle(brush, null, new Rect(x * w, 0, w, this.ActualHeight));
}
}
}
}
}
The problem is that my control doesn't redraw itself when i change elements in the underlying array. It works fine when i assign a whole new array or resize the control though.
Obviously I need another class which somehow notifies control about internal changes in the collection. I was looking at INotifyCollectionChange and ObservableCollection but the only articles I found were about binding collections to existing controls, not custom user-drawn ones. So I got confused and stuck at this point.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可能可以为自己创建一个类似于 2D 数组的自定义集合,但您还需要实现 INotifyCollectionChange 接口,这并不难实现。这样,WPF 将侦听您的集合更改并在必要时更新控件。
You probably can create a custom collection for yourself that works like your 2D array, but you need to also implement INotifyCollectionChange interface, which is not so hard to implement. That way WPF will listen to your collection changes and update the control if necessary.
我认为示例 可能有用。
I think the sample may be useful.