C# 如何提高向UI添加控件的速度
我有以下代码创建WPF控件,然后以我需要的方式将它们添加到窗口中。它工作正常,但当尝试创建256(x4-两个文本块、组合框、文本框)控件时,显示选项卡需要一些时间。窗口加载很好,但我有很多选项卡,当我单击“点设置”选项卡时,它在显示选项卡之前会稍微滞后一点。它只会在我第一次单击选项卡时延迟,每次单击后它都会立即响应 起初我认为这是一个渲染问题,但经过许多其他研究后,我发现C#/WPF在动态创建一组对象并将其添加到表单中时效果不佳 如果我把项目数降到50,它会立即响应,100是一个轻微的延迟,200(256)是一个稍微多的延迟,太多了,用户无法接受 以前有过类似问题的经验,以及如何修复的建议或其他提示/技巧 提前谢谢! 卫斯理C# 如何提高向UI添加控件的速度,c#,wpf,performance,user-interface,rendering,C#,Wpf,Performance,User Interface,Rendering,我有以下代码创建WPF控件,然后以我需要的方式将它们添加到窗口中。它工作正常,但当尝试创建256(x4-两个文本块、组合框、文本框)控件时,显示选项卡需要一些时间。窗口加载很好,但我有很多选项卡,当我单击“点设置”选项卡时,它在显示选项卡之前会稍微滞后一点。它只会在我第一次单击选项卡时延迟,每次单击后它都会立即响应 起初我认为这是一个渲染问题,但经过许多其他研究后,我发现C#/WPF在动态创建一组对象并将其添加到表单中时效果不佳 如果我把项目数降到50,它会立即响应,100是一个轻微的延迟,20
public static void pointSetup(virtualzingstackpanel desc,virtualzingstackpanel map)//在点设置选项卡中绘制点描述和点映射表
{
堆垛板排;
文本块文本;
文本框文本框;
组合框组合框;
厚度行间距=新厚度(0,0,0,5);
厚度text间距=新厚度(0,3,5,3);
列表=新列表();
列表。添加(“xx”);
对于(字节i=0;i
新代码(使用DataTemplate和ItemsControl)
公共类设备点
{
公共字符串desc{get;set;}
公共int区域{get;set;}
公共列表区域{get;set;}
}
//初始化所有变量并显示UI(构造函数)
公共调度程序()
{
初始化组件();
列表选项=新列表();
选择添加(“xx”);
对于(字节i=0;i
M.Moshe请注意,通过使用代码创建对象,您实际上否定了虚拟化系统,该系统有助于克服一次性创建大量控件对性能的影响。我建议重新构造此代码,将
项控件
与项模板
结合使用,而不是使用旧的WinForms通过代码直接添加控件的方法。在名为BeginUpdate
的“父”控件上,可能有某种方法会暂停更新UI,直到您调用EndUpdate
,但我不是100%确定。您还显式地使用了VirtualzingStackPanels,但通过直接添加作为补充说明,ItemsControl
本机不支持虚拟化(它主要是为ListBox
添加的)使用所描述的技术,您仍然可以获得所需的行为。@WesleyCarlsen,这是一个大话题;讨论了一点WPF内容模型及其使用方法。一旦您开始使用数据模板,其余的都会到位。不幸的是,所有控件都需要添加到UI线程上,这意味着并行是不可能的t、 我还怀疑重新分配该名单的支持库是否值得注意
public static void pointSetup(VirtualizingStackPanel desc, VirtualizingStackPanel map) //Draws point description and point map table in point setup tab
{
StackPanel row;
TextBlock text;
TextBox textBox;
ComboBox comboBox;
Thickness rowSpacing = new Thickness(0, 0, 0, 5);
Thickness textSpacing = new Thickness(0, 3, 5, 3);
List<string> list = new List<string>();
list.Add("xx");
for (byte i = 0; i < Global.currentZonesToMap; i++)
{
list.Add("Zone " + (i + 1));
}
for (short i = 0; i < 256; i++)
{
//desc
row = new StackPanel();
row.Margin = rowSpacing;
row.Orientation = Orientation.Horizontal;
text = new TextBlock();
text.Text = "Point " + (i + 1);
text.Margin = textSpacing;
text.Width = 50;
textBox = new TextBox();
textBox.MaxLength = 28;
textBox.Text = "";
textBox.Width = 270;
row.Children.Add(text);
row.Children.Add(textBox);
desc.Children.Add(row);
//map
row = new StackPanel();
row.Margin = rowSpacing;
row.Orientation = Orientation.Horizontal;
text = new TextBlock();
text.Text = "Point " + (i + 1);
text.Margin = textSpacing;
text.Width = 50;
comboBox = new ComboBox();
comboBox.ItemsSource = list;
comboBox.Width = 270;
row.Children.Add(text);
row.Children.Add(comboBox);
map.Children.Add(row);
}
}
public class DevicePoint
{
public string desc { get; set; }
public int zone { get; set; }
public List<string> zones { get; set; }
}
//Initialized all variables and displays UI (constructor)
public Dispatcher()
{
InitializeComponent();
List<string> opts = new List<string>();
opts.Add("xx");
for (byte i = 0; i < Global.currentZonesToMap; i++)
{
opts.Add("Zone " + (i + 1));
}
List<DevicePoint> points = new List<DevicePoint>();
for (short i = 0; i < 256; i++)
points.Add(new DevicePoint() { desc = "Point " + (i + 1), zone = 0, zones = opts });
pointDesc.ItemsSource = points;
pointZoneMap.ItemsSource = points;
... other stuff here ...
}
<StackPanel>
<TextBlock Margin="10" FontWeight="Bold" HorizontalAlignment="Center" Text="Point Descriptions" />
<ScrollViewer Width="360" Margin="30,10,30,10" MaxHeight="405">
<ItemsControl Name="pointDesc" Margin="5">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel VirtualizingStackPanel.IsVirtualizing="True" Margin="0,0,0,5" Orientation="Horizontal">
<TextBlock Margin="0,3,5,3" Width="50" Text="{Binding desc}" />
<TextBox MaxLength="28" Width="270" Text="{Binding desc}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Margin="10" FontWeight="Bold" HorizontalAlignment="Center" Text="Point - Zone Map" />
<ScrollViewer Width="360" Margin="30,10,30,10" MaxHeight="405">
<ItemsControl Name="pointZoneMap" Margin="5">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel VirtualizingStackPanel.IsVirtualizing="True" Margin="0,0,0,5" Orientation="Horizontal">
<TextBlock Margin="0,3,5,3" Width="50" Text="{Binding desc}" />
<ComboBox Width="270" ItemsSource="{Binding zones}" SelectedIndex="{Binding zone}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>