Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用大量控件提高Winforms性能_C#_.net_Winforms - Fatal编程技术网

C# 使用大量控件提高Winforms性能

C# 使用大量控件提高Winforms性能,c#,.net,winforms,C#,.net,Winforms,在构造包含大量控件(500+)的多个表单时,是否有任何方法可以提高性能 我们的控件以每行6个文本框的方式排列,如下所示: 我们使用了以下容器来构建我们的控件: DevExpress的XtraLayoutControl 环绕每行并手动移动的面板 公共表控件 我们不能使用网格,因为文本框必须逐个隐藏,我们的表单必须看起来非常接近打印输出。此外,每一行都有自己的数据类型,因此我们需要为每一行添加验证和编辑器 table控件是性能最好的,每个表单加载大约需要2秒钟 由于其中每一个都将在我们的软件中

在构造包含大量控件(500+)的多个表单时,是否有任何方法可以提高性能

我们的控件以每行6个文本框的方式排列,如下所示:

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

  • DevExpress的XtraLayoutControl
  • 环绕每行并手动移动的面板
  • 公共表控件
我们不能使用网格,因为文本框必须逐个隐藏,我们的表单必须看起来非常接近打印输出。此外,每一行都有自己的数据类型,因此我们需要为每一行添加验证和编辑器

table控件是性能最好的,每个表单加载大约需要2秒钟

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

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

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

有没有其他可用的策略,或者我们应该直接告诉我们的客户,这个程序将比它的VB6前身慢


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

我们不能使用网格,因为文本框必须逐个隐藏。

我不明白为什么这会阻止使用
DataGridView
。通过将
ReadOnly
属性设置为
true
,可以将特定的
DataGridViewCell
设置为只读。然后可以使用
DataGridView.CellFormatting
事件隐藏只读单元格的值。如果我没记错的话,代码类似于:

private void grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    DataGridView grid = (DataGridView)sender;
    if (grid[e.ColumnIndex, e.RowIndex].ReadOnly)
    {
        e.Value = string.Empty;
        e.FormattingApplied = true;
    }
}

对于您来说,复杂的数据类型处理和内容非常重要,这是一个午餐前5分钟的示例,用于显示winforms有多么糟糕以及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");
    }
}
}
命名空间WpfApplication5
{
公共部分类主窗口:窗口
{
私人物品清单;
公共清单项目
{
获取{return\u items???(\u items=new List());}
}
公共主窗口()
{
初始化组件();
添加(新项(){Description=“贱金属厚度”});
对于(变量i=32;i>0;i--)
{
添加(新项(){Description=“Metal Specification”+i.ToString()});
}
添加(新项(){Description=“贱金属规范”});
DataContext=this;
}
}
公共类项目:INotifyPropertyChanged
{
私有列表值;
公共列表值
{
获取{返回_值???(_值=新列表());}
}
公共事件属性更改事件处理程序属性更改;
公共字符串说明{get;set;}
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
var handler=PropertyChanged;
if(处理程序!=null)
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
公共项目()
{
价值。添加(“价值1”);
价值。添加(“价值2”);
价值。添加(“价值3”);
价值。添加(“价值4”);
价值。添加(“价值5”);
价值。添加(“价值6”);
}
}
}
XAML:


我知道你还有其他一些要求,比如隐藏文本框之类的东西。如果这些行是不同的数据类型,这无关紧要,您只需要执行一个视图模型(在这种情况下,它将是我的
公共类项目
,它保存您希望在屏幕上显示的数据,并让用户能够与之交互

例如,您可以用更复杂的内容替换
类中的
列表
,并添加一些属性,如
public bool IsVisible{get;set;}

我强烈建议您看看WPF(至少在这个屏幕上)


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

我对oop非常幼稚,但是,您真的必须同时提交所有这些数据吗?(我假设您只有一个按钮)如果我是你,我只会在gui的前2行添加put。我会提供一个循环,告诉用户键入金属规格2,然后是第3行,然后是第4行…(a)嗨,帖木儿,这是一个没有你在这里所说的那种流程的程序。用户以一种自上而下的顺序填写细节,但不是明确的。这是一个测试设置,完整的文档要复杂得多,线性得少。例如:解决方案:WPF。Winforms很烂,速度很慢。Brass不会相信我是af团队中没有人在WPF方面有任何独家经验,因此开发时间将飞速增长:(嗨,Ginosaji,请参阅我的编辑,以了解我们正在重新开发的表单的示例。我们的软件以正在编辑的表单与打印输出外观相同而闻名。不幸的是,我们无法采用这种方法。此外,每行都有自己的单独数据类型。并且它们是数据绑定的。我有太多的限制,没有足够的选项!您可以创建一个consistent
ViewModel
用于绑定到的行。
ViewModel
的具体实现将执行与基础数据之间的各种转换
<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>