2017-06-08 6 views
0

私の入力情報のグリッドビューの種類を表示するために使用する次のWPF C#コードが非常に遅く、特にそれをどのように順番に改善するのかを理解しようとしています。コントロールのレンダリングを高速化します。次のWPF UIコードを高速化するには

I以下の入力、すなわち、ユーザの選択に応じて変化することができる持っている:

public class Field 
{ 
    public string Key; 
    public Tuple<string, bool> Value; 
} 


var fields = new List<Field>(); 
// fill fields... 

各フィールドのために私はVirtualizingStackPanelに挿入されたコントロール作成:

StackPanelFields.Children.Clear(); 
foreach (var f in fields) 
    StackPanelFields.Children.Add(GetFieldControl(f.Key, f.Value)); 


private Grid GetFieldControl(string name, Tuple<string, bool> value) 
{ 
    Debug.Assert(!String.IsNullOrWhiteSpace(name)); 
    Debug.Assert(value != null); 

    // two-column grid 
    var grid = new Grid(); 
    grid.ColumnDefinitions.Add(new ColumnDefinition()); 
    grid.ColumnDefinitions.Add(new ColumnDefinition()); 

    var color = value.Item2 ? Brushes.Black : Brushes.Red; 

    var nameTextblock = new TextBlock { Text = name, Margin = new Thickness(5, 0, 0, 5), Foreground = color }; 
    grid.Children.Add(nameTextblock); 

    // value 
    var valueTextBox = new TextBox 
    { 
     Text = value.Item1, 
     Foreground = color, 
     TextWrapping = TextWrapping.Wrap, 
     IsReadOnly = true, 
     BorderThickness = new Thickness(0) 
    }; 

    Grid.SetColumn(valueTextBox, 1); 
    grid.Children.Add(valueTextBox); 

    return grid; 
} 

数フィールドの平均は1000-2000です。私のマシンでは、VirtualizingStackPanelは1秒以上必要です。私はこの時間を測定していませんが、それはユーザーにとって非常に遅いことは明らかです。

+1

[仮想化](httpsでテンプレートを使用してみてくださいです:// msdn.micros oft.com/en-us/library/system.windows.controls.virtualizingstackpanel(v=vs.110).aspx) –

+0

オプションのページングのようなものですか? –

+0

@JeroenvanLangen各フィールドのリストのStackPanelをセカンダリストレージに保存することについて話していますか?このリストの数(可能なユーザーの選択肢)は10kまで増やすことができます。 – Nick

答えて

0

私は1.000.000アイテム(さらにはそれ以上)を提示することに問題はなく、データコレクションを作成してからそれを提示するまでに時間がかかります。

Modelクラス

public class Field : ObservableObject 
{ 
    private string _name; 
    private string _value; 
    private bool _flag; 

    public string Name { get => _name; set => Set(ref _name, value); } 
    public string Value { get => _value; set => Set(ref _value, value); } 
    public bool Flag { get => _flag; set => Set(ref _flag, value); } 
} 

MainViewModel

public class MainViewModel : ViewModelBase 
{ 
    private int _fieldcount; 
    private ObservableCollection<Models.Field> _fields; 

    public MainViewModel() 
    { 
     if (IsInDesignMode) 
     { 
      _fieldcount = 100; 
     } 
     else 
     { 
      _fieldcount = 1000000; 
     } 

     Initialize(); 

    } 

    private void Initialize() 
    { 
     var fieldquery = Enumerable.Range(1, _fieldcount).Select(e => new Models.Field { Name = $"Field {e}", Value = $"Value {e}", Flag = false, }); 
     Fields = new ObservableCollection<Models.Field>(fieldquery); 
    } 

    public ObservableCollection<Models.Field> Fields { get => _fields; set => Set(ref _fields, value); } 

} 

ビュー

<Window x:Class="WpfApp6.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:models="clr-namespace:WpfApp6.Models" 
     xmlns:local="clr-namespace:WpfApp6" 
     mc:Ignorable="d" 
     DataContext="{Binding Source={StaticResource Locator}, Path=Main}" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <ItemsControl VirtualizingStackPanel.IsVirtualizing="True" 
         ScrollViewer.CanContentScroll="True" 
         ItemsSource="{Binding Path=Fields}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate DataType="{x:Type models:Field}"> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition/> 
          <ColumnDefinition/> 
         </Grid.ColumnDefinitions> 
         <TextBlock Grid.Column="0" Text="{Binding Name}" /> 
         <TextBox Grid.Column="1" Text="{Binding Value}" IsReadOnly="True"/> 
        </Grid> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <VirtualizingStackPanel /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.Template> 
       <ControlTemplate> 
        <Border BorderThickness="{TemplateBinding Border.BorderThickness}" 
          Padding="{TemplateBinding Control.Padding}" 
          BorderBrush="{TemplateBinding Border.BorderBrush}" 
          Background="{TemplateBinding Panel.Background}" 
          SnapsToDevicePixels="True"> 
         <ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False"> 
          <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> 
         </ScrollViewer> 
        </Border> 
       </ControlTemplate> 
      </ItemsControl.Template> 
     </ItemsControl> 
    </Grid> 
</Window> 

プロジェクト全体がhere

+0

あなたの答えをありがとうが、私はあなたのソリューションをコンパイルできません。エラーを修正してプロジェクトを実行すると、何も表示されません。 – Nick

+0

どのようなエラーがありますか? VS2017CEでコンパイルしました。 githubに問題を投稿することができます –

関連する問題