在wpf容器网格

时间:2017-08-04 03:47:30

标签: c# wpf performance xaml scrollviewer

我正在基于某些对象创建动态UI,并且由于要渲染的项目数量很多,因此加载会花费大量时间。 见下面的xml: -

 <ScrollViewer Grid.Row="2" ZoomMode="Enabled" x:Name="scrollviewer"  
        VirtualizingStackPanel.VirtualizationMode="Recycling"
        HorizontalScrollMode="Auto"
        VerticalScrollMode="Auto"
        VerticalSnapPointsType="None"
        HorizontalSnapPointsType="None"
        HorizontalScrollBarVisibility="Auto"
        VerticalScrollBarVisibility="Auto"
        MinZoomFactor="1" IsDoubleTapEnabled="True"
        RenderTransformOrigin="0,0">
        <Grid Background="#FFDDE6EB" x:Name="mygrid" VerticalAlignment="Center" HorizontalAlignment="Center">

        </Grid>
    </ScrollViewer>

scrollviewer位于一行中,高度为10 *。

动态加载项目的代码如下: -

  public static Grid LoadGridWithItems(Model m)
        {

            var grid = new Grid();
            grid.UseLayoutRounding = true;
            grid.RowDefinitions.Clear();
            grid.ColumnDefinitions.Clear();

            int count = m.Rows;
            for (int i = 0; i < count; i++)
            {
                grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
            }

            count = m.Columns;
            for (int i = 0; i < count; i++)
            {
                grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(m.GetColumnWidth(i), GridUnitType.Star) });
            }
            foreach (Control control in m.Controls)
            {
          UIElement uicontrol=null;
                if (control.Type != null)
                {

                    switch (control.Type.ToLower())
                    {
                        case "textbox":
                             uicontrol=new TextBox();
                            break;
                        case "label":
                            uicontrol = new Label();;
                            break;

                      //bunch of other custom controls
                    }
                  }


                grid.Children.Add(uicontrol);
            }
            return grid;
        }

然后将生成的网格作为子项添加到上面xaml中定义的“mygrid”。有时项目超过5000,加载大约需要20-25秒。 有关如何以更好的方式实施此方案的任何建议吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

如果使用ItemsControl和MVVM,则可以提高代码质量和可读性。此外,我认为表现会得到提升。像这样:

<ItemsControl ItemsSource="{Binding yourControlCollection}">
  <!-- Templates for your controls -->
  <ItemsControl.Resources>
    <DataTemplate DataType="{x:Type yourNameSpace:ComboBoxControl}">
        <ComboBox />
    </DataTemplate>

    <DataTemplate DataType="{x:Type yourNameSpace:TextControl}">
        <TextBox />
    </DataTemplate>
  </ItemsControl.Resources>
</ItemsControl>

此外,您可以更轻松地获取用户在表单上引入的值。您可以将值绑定到模型类中的属性,然后就可以了。

public class TextControl
{
  public string TextValue { get; set; }
}

<DataTemplate DataType="{x:Type yourNameSpace:TextControl}">
  <TextBox Text="{Binding TextValue}" />
</DataTemplate>

修改。样品

XAML:

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication2"
    Title="MainWindow" Height="350" Width="525">
<ItemsControl ItemsSource="{Binding List}">
    <ItemsControl.Resources>
        <DataTemplate DataType="{x:Type local:ControlText}">
            <StackPanel Orientation="Horizontal" Background="Yellow">
                <TextBlock Text="{Binding Label}" />
                <TextBlock Text="{Binding Text}" />
            </StackPanel>
        </DataTemplate>

        <DataTemplate DataType="{x:Type local:ControlBool}">
            <StackPanel Orientation="Horizontal" Background="Orange">
                <TextBlock Text="{Binding Label}" />
                <CheckBox IsChecked="{Binding Value}" />
            </StackPanel>
        </DataTemplate>

    </ItemsControl.Resources>
</ItemsControl>

CS:

using System;
using System.Collections.Generic;
using System.Windows;

namespace WpfApplication2
{
public partial class MainWindow : Window
{
    public IEnumerable<Control> List { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        DataContext = this;

        var l = new List<Control>();
        l.Add(new ControlText() { Text = "Michael", Label = "Name" });
        l.Add(new ControlBool() { Value = true, Label = "C#" });
        l.Add(new ControlBool() { Value = false, Label = "WPF" });
        l.Add(new ControlText() { Text = "Martinez", Label= "Surname" });

        List = l;
    }
}

public abstract class Control
{
    public String Label { get; set; }
}

public class ControlText : Control
{
    public String Text { get; set; }
}

public class ControlBool : Control
{
    public Boolean Value { get; set; }
}
}

:D

答案 1 :(得分:1)

我们同样存在添加子控件缓慢的问题。造成这种情况的可能原因是,它们是自下而上(在树中)添加的,而自上而下添加它们的速度则异常快。在以下站点中对此进行了全部解释: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-layout-and-design 从中链接的页面是如何充分利用WPF的金矿。