Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.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# 如何提高向UI添加控件的速度_C#_Wpf_Performance_User Interface_Rendering - Fatal编程技术网

C# 如何提高向UI添加控件的速度

C# 如何提高向UI添加控件的速度,c#,wpf,performance,user-interface,rendering,C#,Wpf,Performance,User Interface,Rendering,我有以下代码创建WPF控件,然后以我需要的方式将它们添加到窗口中。它工作正常,但当尝试创建256(x4-两个文本块、组合框、文本框)控件时,显示选项卡需要一些时间。窗口加载很好,但我有很多选项卡,当我单击“点设置”选项卡时,它在显示选项卡之前会稍微滞后一点。它只会在我第一次单击选项卡时延迟,每次单击后它都会立即响应 起初我认为这是一个渲染问题,但经过许多其他研究后,我发现C#/WPF在动态创建一组对象并将其添加到表单中时效果不佳 如果我把项目数降到50,它会立即响应,100是一个轻微的延迟,20

我有以下代码创建WPF控件,然后以我需要的方式将它们添加到窗口中。它工作正常,但当尝试创建256(x4-两个文本块、组合框、文本框)控件时,显示选项卡需要一些时间。窗口加载很好,但我有很多选项卡,当我单击“点设置”选项卡时,它在显示选项卡之前会稍微滞后一点。它只会在我第一次单击选项卡时延迟,每次单击后它都会立即响应

起初我认为这是一个渲染问题,但经过许多其他研究后,我发现C#/WPF在动态创建一组对象并将其添加到表单中时效果不佳

如果我把项目数降到50,它会立即响应,100是一个轻微的延迟,200(256)是一个稍微多的延迟,太多了,用户无法接受

以前有过类似问题的经验,以及如何修复的建议或其他提示/技巧

提前谢谢! 卫斯理

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
  • 如果您的计算机有多个内核,我假设它有,请尝试并行执行for循环(parallelfor(来自.NET4或更高版本)
  • 您可以在创建期间将点列表大小设置为256,这将阻止在项目添加操作期间分配内存
  • 如果Global.currentZonesToMap较大,请考虑使用StringBuilder
  • 使用StringBuilder生成DevicePoint.desc字符串属性的值
  • 祝你好运


    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>