首页 / C# / c# – 自定义绘制控件的糟糕表现
c# – 自定义绘制控件的糟糕表现
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 自定义绘制控件的糟糕表现,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3530字,纯文字阅读大概需要6分钟。
内容图文
![c# – 自定义绘制控件的糟糕表现](/upload/InfoBanner/zyjiaocheng/818/52db0c5af85b4f72851e4fb2d4f998fe.jpg)
我在wpf中进行简单的图形控制.我无法解释或解决性能问题:与winforms相比,它太慢了.也许我做错了什么.
我准备演示来演示这个问题.
这是测试控制:
public class Graph : FrameworkElement
{
private Point _mouse;
private Point _offset = new Point(500, 500);
public Graph()
{
Loaded += Graph_Loaded;
}
private void Graph_Loaded(object sender, RoutedEventArgs e)
{
// use parent container with background to receive mouse events too
var parent = VisualTreeHelper.GetParent(this) as FrameworkElement;
if (parent != null)
parent.MouseMove += (s, a) => onm ouseMove(a);
}
protected override void OnRender(DrawingContext context)
{
// designer bugfix
if (DesignerProperties.GetIsInDesignMode(this))
return;
Stopwatch watch = new Stopwatch();
watch.Start();
// generate some big figure (try to vary that 2000!)
var radius = 1.0;
var figures = new List<LineSegment>();
for (int i = 0; i < 2000; i++, radius += 0.1)
{
var segment = new LineSegment(new Point(radius * Math.Sin(i) + _offset.X, radius * Math.Cos(i) + _offset.Y), true);
segment.Freeze();
figures.Add(segment);
}
var geometry = new PathGeometry(new[] { new PathFigure(figures[0].Point, figures, false) });
geometry.Freeze();
var pen = new Pen(Brushes.Black, 5);
pen.Freeze();
context.DrawGeometry(null, pen, geometry);
// measure time
var time = watch.ElapsedMilliseconds;
Dispatcher.InvokeAsync(() =>
{
Window.GetWindow(this).Title = string.Format("{0:000}ms; {1:000}ms", time, watch.ElapsedMilliseconds);
}, DispatcherPriority.Loaded);
}
protected override void onm ouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
var mouse = e.GetPosition(this);
if (e.LeftButton == MouseButtonState.Pressed)
{
// change graph location
_offset.X += mouse.X - _mouse.X;
_offset.Y += mouse.Y - _mouse.Y;
InvalidateVisual();
}
// remember last mouse position
_mouse = mouse;
}
}
以下是如何在xaml中使用它:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<Grid Background="White">
<local:Graph/>
</Grid>
</Window>
一些评论:控件将绘制图形,可以通过鼠标移动:
它将在标题中显示2个测量值:第一个是OnRender()完成所需的时间,第二个是实际渲染需要多长时间(渲染后首次调用).
尝试改变2000:设置1000使移动舒适,3000在重新绘制图形之前就像半秒延迟(在我的电脑上).
问题:
>使用InvalidateVisual()更新MouseMove中的图形偏移量是否合适?如果不好,什么是无效的正确技术?
>冻结,其中有许多没有任何明显的影响.我是否需要使用它们?
>看起来完成渲染只需要5ms,但主观移动需要更长的时间(200ms).这是为什么?
主要问题当然是表现,为什么这么可怕?我可以在winform控件中绘制几十万行,直到它变得像马虎一样,因为我的wpf控件仅用1000 … =(
我在最后一个问题上找到答案.使用鼠标移动时,测量渲染时间无法正常工作.但是如果窗口调整大小,那么第二次变为300ms(在我的PC上有2000个数字).所以这不是一个错误的鼠标无效(第一个问题),但实际上渲染速度非常慢.
解决方法:
这是WPF不太擅长的一项任务.我的意思是一般的矢量图形.感谢保留模式.它适用于控件渲染,但不适用于您经常更新的繁忙图表.我在尝试在WPF地图上渲染GPS轨道时遇到了同样的问题.
我建议使用direct2d并在WPF中托管它.像这样的东西:
http://www.codeproject.com/Articles/113991/Using-Direct-D-with-WPF
这将为您带来高性能.
PS别误会我的意思. WPF没什么不好的.它旨在解决具体问题.构建控件和构建令人印象深刻的UI非常容易.我们从自动布局系统中获得了很多理所当然的东西.但是在任何可能的情况下它都不是很聪明,微软并没有很好地解释这些情况,因为它不是一个好的选择.让我给你举个例子. IPad具有高性能,因为它具有固定的分辨率和绝对的布局.如果您修复WPF窗口大小并使用画布面板,您将获得相同的体验.
内容总结
以上是互联网集市为您收集整理的c# – 自定义绘制控件的糟糕表现全部内容,希望文章能够帮你解决c# – 自定义绘制控件的糟糕表现所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。