我正在基于某些对象创建动态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秒。 有关如何以更好的方式实施此方案的任何建议吗?
谢谢!
答案 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; }
}
}
答案 1 :(得分:1)
我们同样存在添加子控件缓慢的问题。造成这种情况的可能原因是,它们是自下而上(在树中)添加的,而自上而下添加它们的速度则异常快。在以下站点中对此进行了全部解释: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-layout-and-design 从中链接的页面是如何充分利用WPF的金矿。