canvas绘制控件
使用canvas启动绘制label控件,10000个需要2-3s的时间
代码语言:javascript复制for (int i = 0; i < 10000; i )
{
canvas.Children.Add(new Label() { Content = i.ToString(), BorderBrush = Brushes.Black, BorderThickness = new Thickness(3), FontSize = 40 });
Canvas.SetLeft(canvas.Children[canvas.Children.Count - 1], rd.Next(0, (int)canvas.ActualWidth - 100));
Canvas.SetTop(canvas.Children[canvas.Children.Count - 1], rd.Next(0, (int)canvas.ActualHeight - 100));
}
drawvisual绘制
使用drawvisual绘制,需要重载封装控件
代码语言:javascript复制public class DrawVisualShow :FrameworkElement
{
Random rd = new Random();
readonly VisualCollection _children;
public DrawVisualShow(Window win)
{
_children = new VisualCollection(this);
for (int i = 0; i < 10000; i )
{
Point pt = new Point((double)rd.Next(0, (int)win.ActualWidth - 100),
(double)rd.Next(0, (int)win.ActualHeight - 100));
DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();
dc.DrawRectangle(Brushes.Green, new Pen(Brushes.Black, 3), new Rect(pt.X, pt.Y, 20, 10));
dc.DrawText(new FormattedText(i.ToString(), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Arial"), 10, Brushes.Red), new Point(pt.X 10, pt.Y 5));
dc.Close();
_children.Add(dv);
}
}
protected override int VisualChildrenCount
{
get { return _children.Count; }
}
protected override Visual GetVisualChild(int index)
{
return _children[index];
}
}
在window中添加
AddChild(new DrawVisualShow(this));
添加10000个图形节点大约1-2s,10w个图形需要5-6s,还是很慢,绘制的时候会调用gpu,但效率没提升多少,使用drawvisual还有一个问题是内存很高。
wpf使用gdi
定义属性成员
代码语言:javascript复制System.Drawing.Image _bitmap;
public BitmapImage BitmapSource
{
get
{
MemoryStream _ms = new MemoryStream();
_bitmap.Save(_ms, ImageFormat.Png);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = _ms;
bitmapImage.EndInit();
return bitmapImage;
}
}
调用gdi 绘制,10000个1-2s,10w个3-4s
代码语言:javascript复制_bitmap = new System.Drawing.Bitmap((int)ActualWidth, (int)ActualHeight);
using (Graphics g = Graphics.FromImage(_bitmap)) {
for (int i = 0; i < 100000; i )
{
System.Windows.Point pt = new System.Windows.Point((double)rd.Next(0, (int)ActualWidth - 100),
(double)rd.Next(0, (int)ActualHeight - 100));
System.Drawing.Rectangle rt =new System.Drawing.Rectangle((int)pt.X,(int)pt.Y,20,10);
g.DrawRectangle(new System.Drawing.Pen(System.Drawing.Brushes.Black, 3), rt);
g.DrawString(i.ToString(), new Font("Arial", 15), System.Drawing.Brushes.Black, rt, new StringFormat()
{ Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
}
image.Source = BitmapSource;
}
绘图框架在选取前,最好做个简单的性能测试,坑太多注意避坑。 wpf使用UIElement绘制,通过事件响应机制绘制,事件响应有很多坑
wpf中的一些坑
wpf是c#中快速开发ui的框架,你面有很多坑汇总一下
- FrameworkElement的parent获取不到父节点
wpf有显示树和逻辑树结构,使用VisualTreeHelper.GetParent可以获取parent获取不到的父节点
- mousemove不连续,mouseup事件丢失(mousemove状态监测)
mousemove事件不连续,需要CaptureMouse、ReleaseMouseCapture 个人经历,在做拖拽矩形时,位置计算的点在left、top位置,没有在矩形中心区域计算错误导致,拖拉异常
- dragenter、dragleave事件错误,没找到原因,只能尽量避免使用
- usercontorl不响应keydown的问题
windows窗口中添加keydown,传递到usercontrol中来