c# - 通过大量控件提高 Winforms 性能

标签 c# .net winforms

在构建具有大量控件(500+)的多个表单时,有什么方法可以提高性能吗?

我们的控件采用每行一个标签 + 6 个文本框的配置,如下所示:

Image

我们使用以下容器来构建我们的控件:

  • DevExpress 的 XtraLayoutControl
  • 每行周围的面板并手动移动
  • 通用表格控件

我们不能使用网格,因为文本框必须根据具体情况隐藏,并且我们的表单必须看起来与打印输出相当接近。此外,每一行都有自己的数据类型,因此我们需要为每一行添加验证和编辑器。

表格控件的性能最高,每个表单加载大约需要 2 秒。

由于每个文件都代表我们软件中的一个文档,并且我们允许用户一次打开多个文档,因此我们正在尝试找到一种提高性能的方法。

一个建议是缓存实际表单并拥有一个存储数据的状态对象。但是,我们允许用户同时查看多个文档。

另一个建议是分部分加载文档并在加载时显示每个部分。这并不理想,因为众所周知,我们的文档看起来几乎与打印输出一模一样。

是否还有其他可用的策略,或者我们应该硬着头皮告诉我们的客户,该程序将比它的 VB6 前身慢?

我们正在重新开发的表单设计示例如下:Link

最佳答案

复杂的数据类型处理和东西适合你,这是午餐前 5 分钟的示例,展示了 winform 有多糟糕以及 WPF 规则有多少:

namespace WpfApplication5
{

public partial class MainWindow : Window
{
    private List<Item> _items;
    public List<Item> Items
    {
        get { return _items ?? (_items = new List<Item>()); }
    }

    public MainWindow()
    {
        InitializeComponent();

        Items.Add(new Item() {Description = "Base metal Thickness"});

        for (var i = 32; i > 0; i--)
        {
            Items.Add(new Item() {Description = "Metal Specification " + i.ToString()});
        }

        Items.Add(new Item() { Description = "Base metal specification" });

        DataContext = this;
    }
}

public class Item: INotifyPropertyChanged
{
    private List<string> _values;
    public List<string> Values
    {
        get { return _values ?? (_values = new List<string>()); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public string Description { get; set; }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null) 
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public Item()
    {
        Values.Add("Value1");
        Values.Add("Value2");
        Values.Add("Value3");
        Values.Add("Value4");
        Values.Add("Value5");
        Values.Add("Value6");
    }
}
}

XAML:

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <ItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Description}" Width="130"/>
                    <ItemsControl ItemsSource="{Binding Values}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal"/>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBox Text="{Binding Path=.}" Margin="2" Width="90"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

我发现您这里还有其他几个要求,例如隐藏文本框之类的东西。这些行是否是不同的数据类型并不重要,您只需要执行一个 ViewModel (在本例中是我的 public class Item ,它保存您想要在屏幕,并让用户能够与之交互。

例如,您可以替换 List<string>里面Item类具有更复杂的内容,并添加一些属性,例如 public bool IsVisible {get;set;}等等。

我强烈建议您看一下 WPF(至少对于这个屏幕而言)。

将我的代码复制并粘贴到新的 -> WPF 项目中,您可以亲自查看结果。

关于c# - 通过大量控件提高 Winforms 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14565773/

相关文章:

c# - 用一行代码填充 Enumerable.ToList

.net - 在单独的线程中运行 Windows 窗体

c# - 我希望是一个简单的 C# 问题!向按钮添加其他属性

c# - Mysql 连接器.Net : FormatException when trying to execute a command with parameters.

c# - 如果在析构函数中我创建了一个对象的活引用怎么办?

c# - 错误抛出 TypeLoadException

c# - 可以在 Finally block 的中间引发 ThreadAbortException 吗?

c# - 如何获取报告服务实例上可用的报告列表

c# - 如何最好地链接到 API Controller

c# - 序列化锯齿状数组与多维数组