我是Windows Forms开发人员,目前我正在使用WPF。为了对文本框中文本呈现的两种技术进行快速性能比较,我编写了一个小程序,在窗口中创建了大量文本框,并每100ms更新一次文本。
令我惊讶的是,测试应用程序的WPF版本比WinForms版本慢得多。大多数情况下,应用程序根本没有响应,例如当我尝试调整窗口大小时。该应用程序的WinForms版本运行顺利。
所以我的问题是:我使用WPF控件的方式有什么问题(我使用WrapPanel作为WPF中的控件容器和WinForms中的FlowLayoutPanel)?或者文本呈现真的比WinForms慢?
WPF:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace PerformanceTestWPF
{
public partial class MainWindow : Window
{
DispatcherTimer _timer = new DispatcherTimer();
Random _r = new Random();
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 400; i++)
this.wrapPanel.Children.Add(new TextBox {Height = 23, Width = 120, Text = "TextBox"});
_timer.Interval = new TimeSpan(0,0,0,0, 100);
_timer.Tick += _timer_Tick;
_timer.Start();
}
private void _timer_Tick(object sender, EventArgs e)
{
foreach (var child in wrapPanel.Children)
{
var textBox = child as TextBox;
if (textBox != null)
{
textBox.Text = _r.Next(0, 1000).ToString();
}
}
}
}
}
的WinForms:
using System;
using System.Windows.Forms;
namespace PerformanceTestWinforms
{
public partial class Form1 : Form
{
Timer _timer = new Timer();
Random _r = new Random();
public Form1()
{
InitializeComponent();
for (int i = 0; i < 400; i++)
this.flowLayoutPanel1.Controls.Add(new TextBox { Height = 23, Width = 120, Text = "TextBox" });
_timer.Interval = 100;
_timer.Tick += _timer_Tick;
_timer.Start();
}
private void _timer_Tick(object sender, EventArgs e)
{
foreach (var child in flowLayoutPanel1.Controls)
{
var textBox = child as TextBox;
if (textBox != null)
{
textBox.Text = _r.Next(0, 1000).ToString();
}
}
}
}
}
答案 0 :(得分:2)
我认为问题是显式调度,请尝试这个基于绑定的示例:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace WpfPerfTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Timer _timer;
Random _r = new Random();
private readonly List<ValueViewModel<string>> _values = new List<ValueViewModel<string>>();
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 400; i++)
{
var value = new ValueViewModel<string>();
var tb = new TextBox { Height = 23, Width = 120 };
tb.SetBinding(TextBox.TextProperty, new Binding("Value") { Source = value });
this.wrapPanel.Children.Add(tb);
this._values.Add(value);
}
_timer = new Timer(o =>
{
foreach (var value in this._values)
value.Value = _r.Next(0, 1000).ToString();
}, null, 0, 100);
}
}
class ValueViewModel<T> : INotifyPropertyChanged where T : class
{
private T _Value = default(T);
public T Value
{
get { return _Value; }
set
{
if (value != _Value)
{
_Value = value;
OnPropertyChanged("Value");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
在调整大小期间,它仍然会窒息,但除此之外它表现得更好。