在构建具有大量控件(500 +)的多个表单时,有什么方法可以提高性能吗?
我们的控件布局在每行配置的标签+6文本框中,如下所示:
Image http://s7.postimage.org/cdhay2c23/test.png
我们使用以下容器来构建控件:
我们不能使用网格,因为必须根据具体情况隐藏文本框,并且我们的表单必须看起来非常接近打印输出。此外,每一行都有自己的数据类型,因此我们需要为每个行添加验证和编辑器。
表格控件是最高效的,每个表单大约需要2秒钟才能加载。
由于其中每个都代表我们软件中的文档,并且我们允许用户一次打开多个文档,我们正在努力寻找提高性能的方法。
一个建议是缓存实际表单并拥有一个存储数据的状态对象。但是,我们允许用户一次查看多个文档。
另一个建议是将文档分批加载并在加载时显示每个部分。这并不理想,因为我们知道文档几乎与打印输出完全一样。
是否有其他可用的策略,或者我们应该告诉客户这个程序会比VB6前辈慢吗?
我们重新开发的表单设计示例如下:Link
答案 0 :(得分:3)
复杂的数据类型处理和东西是给你的,这是一个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");
}
}
}
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>
我看到你在这里有其他几个要求,例如隐藏texbox和东西。如果这些行是不同的数据类型并不重要,您只需要执行 ViewModel (在这种情况下将是我的public class Item
,其中包含您想要的数据在屏幕上显示,让用户能够与之互动。
例如,您可以将List<string>
类中的Item
替换为更复杂的内容,并添加一些属性,例如public bool IsVisible {get;set;}
等。
我强烈建议你看看WPF(至少在这个屏幕上)。
将我的代码复制并粘贴到新的 - &gt; WPF项目,您可以自己查看结果。
答案 1 :(得分:2)
We can't use a grid as the text boxes have to be hidden on a case-by-case basis.
我不明白为什么这会排除使用DataGridView
。通过将DataGridViewCell
属性设置为ReadOnly
,可以将特定true
设为只读。然后,您可以使用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;
}
}