4

Itemscontrolなどを使用してデータコンテキストを描画するUserControlがあります。同じusercontrolの3つのオブジェクトがありますが、プログラムの起動時に初期化される異なるデータコンテキストを使用しています。問題は、データコンテキストが非常に大きいため、各オブジェクトに約2000のUI要素を描画していることです。これには非常に時間がかかります。WPFが単一のUIThreadで実行されているので、私のコンピューターはこれを描画するために合計CPUパワーの1/8を使用しています。どうすればこれを速くできますか?

コード(DynamicShelViewModelはユーザーコントロールです)

dataContextBestSellers = new DynamicShelfViewModel(_config, dataRepository, ProductSelectionMode.BestSellers);
dataContextNormal = new DynamicShelfViewModel(_config, dataRepository, ProductSelectionMode.Normal);
dataContextFull = new DynamicShelfViewModel(_config, dataRepository, ProductSelectionMode.AllProducts); 
ScrollGrid = new Grid();
ScrollGrid.Children.Add(dataContextBestSellers);
ScrollGrid.Children.Add(dataContextNormal);
ScrollGrid.Children.Add(dataContextFull);

これは、完了するのに約2分かかります。

これはDynamicShelfViewModelのXAMLコードです

<Grid>
    <ItemsControl x:Name="ShelvesControl" VirtualizingStackPanel.IsVirtualizing="True"
                  VirtualizingStackPanel.VirtualizationMode="Recycling" DataContext="{Binding}" Width="{Binding Size.Width}"
                  VerticalAlignment="Top" Height="{Binding Size.Height}" Grid.Column="0" Grid.Row="1"
                  ItemsSource="{Binding ShelvesInViewPort}">
      <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>


          <StackPanel VerticalAlignment="Stretch  " HorizontalAlignment="Stretch" Orientation="Vertical" />
        </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <Grid Name="ShelfGrid" Height="{Binding Height}" MaxHeight="{Binding Height}"
                DataContext="{Binding}">
            <Grid.Background>
              <SolidColorBrush Color="{Binding Color}" />
            </Grid.Background>
            <Grid.RowDefinitions>
              <RowDefinition Height="*" />
              <RowDefinition Height="{Binding SplitterSize}" />

            </Grid.RowDefinitions>
            <TextBlock Name="stretchingLabel" Height="{Binding SplitterSize}" Padding="0" Grid.Row="1"
                       VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
              <TextBlock.Background>
                <ImageBrush
ImageSource="{Binding Converter={Utilities1:FancySourceConverter}, ConverterParameter=Images/ShelvesImages/shelfhorisontal.png}" />
              </TextBlock.Background>
              <Grid VerticalAlignment="Stretch"
                    Width="{Binding ElementName=stretchingLabel,Path=ActualWidth}"
                    Height="{Binding ElementName=stretchingLabel,Path=ActualHeight}" HorizontalAlignment="Stretch">
                <Grid.RowDefinitions>
                  <RowDefinition Height="0.24*" />
                  <RowDefinition Height="0.62*" />
                  <RowDefinition Height="0.24*" />
                </Grid.RowDefinitions>
                <my:CategoryLine VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1"
                                 DataContext="{Binding ElementName=ShelfGrid, Path=DataContext}">
                </my:CategoryLine>
              </Grid>
            </TextBlock>

            <TextBlock Name="stretchedLabel" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
                       Grid.Row="0" Padding="0">
              <ItemsControl ItemsSource="{Binding Products}" VerticalAlignment="Stretch"
                            HorizontalAlignment="Stretch">
                <ItemsControl.ItemsPanel>
                  <ItemsPanelTemplate>

                    <UniformGrid DataContext="{Binding}"
                                 Width="{Binding ElementName=stretchedLabel, Path=ActualWidth}"
                                 MaxHeight="{Binding ElementName=stretchedLabel, Path=ActualHeight}"
                                 Height="{Binding ElementName=stretchedLabel, Path=ActualHeight}"
                                 Columns="{Binding Path=DataContext.Slots, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}" Rows="1"
                                 VerticalAlignment="Stretch" Name="ParentUniformGrid" HorizontalAlignment="Stretch" />

                  </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                  <DataTemplate>


                    <ItemsControl>


                      <Grid Height="{Binding ElementName=stretchedLabel, Path=ActualHeight}"
                            VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                        <Grid.RowDefinitions>
                          <RowDefinition Height="*" />
                          <RowDefinition
Height="{Binding ElementName=ParentUniformGrid,Path=DataContext.SplitterSize}" />
                        </Grid.RowDefinitions>
                        <Image VerticalAlignment="Bottom" Grid.Row="0"
                               HorizontalAlignment="Center" x:Name="ProductImage" Source="{Binding Converter={Utilities:ProductImageConverter}}"
                               Height="{Binding ImageHeight}" MaxHeight="{Binding ImageHeight}" MouseLeftButtonUp="BuyProductUsingImage" />
                        <Label Padding="0" Margin="0 1 0 0" Grid.Row="1" Background="LightGray"
                               VerticalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
                               HorizontalAlignment="Stretch">
                          <Label VerticalAlignment="Center" Margin="1"
                                 HorizontalAlignment="Center" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Background="#fff"
                                 Padding="0" MaxWidth="{Binding ElementName=ShelvesControl, Path=DataContext.PriceLabelWidthSize}"
                                 Width="{Binding ElementName=ShelvesControl, Path=DataContext.PriceLabelWidthSize}">
                            <Viewbox VerticalAlignment="Center"
                                     HorizontalAlignment="Center">
                              <StackPanel Orientation="Horizontal"
                                          VerticalAlignment="Bottom" Margin="1" Background="#fff" HorizontalAlignment="Left">
                                <Label Background="Yellow" Padding="2 0 2 0"
                                       VerticalContentAlignment="Bottom" FontWeight="Bold" Content="{Binding Price}">
                                </Label>
                              </StackPanel>
                            </Viewbox>
                          </Label>
                        </Label>


                      </Grid>


                    </ItemsControl>
                  </DataTemplate>
                </ItemsControl.ItemTemplate>
              </ItemsControl>
            </TextBlock>

          </Grid>
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>

  </Grid>
</UserControl>
4

4 に答える 4

0

仮想化にはItemsControl、単なる設定以上のものがありますVirtualizingStackPanel.IsVirtualizing。詳細については、この質問を参照してください

基本的に、仮想化を有効にするItemsControl.Template必要があります。仮想化が正しく行われると、パフォーマンスが劇的に向上するのではないかと思いますScrollViewerItemsControl

仮想化とは、表示されているアイテムのみがレンダリングされることを意味します。スクロールすると、UIコンテナーが再利用され、そのDataContext背後にあるものが変更されます。これは、2000レコードを描画する代わりに、約20レコードしか描画しないことを意味します(または、多くのレコードが表示されます)。

于 2011-11-09T13:26:16.843 に答える
0

についてDataGridは、この記事を見つけました: http ://wpf.codeplex.com/wikipage?title=SelectAll%28%29%20Performance&referringTitle=Tips%20%26%20Tricks&ProjectName=wpf

また、 http://wpf.codeplex.com/discussions/66291?ProjectName = wpf

おそらくそれはすでに役立ちます。

于 2011-11-09T10:10:39.723 に答える
0

およびViewBoxへのバインドなしで同じことを行うと、より軽量な代替手段に置き換えることが可能であれば、非常に役立ちます。ActualWidthActualHeight

于 2011-12-05T18:07:14.127 に答える
0

私の知る限り、より多くの UIThreads を取得する方法は 1 つしかありません。

すべてのウィンドウは、独自の UIThread を持つことができます (例)。

http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/

private void OnCreateNewWindow(object sender, RoutedEventArgs e)
{
    Thread thread = new Thread(() =>
    {
        Window1 w = new Window1();
        w.Show();

        w.Closed += (sender2, e2) =>
        w.Dispatcher.InvokeShutdown();

        System.Windows.Threading.Dispatcher.Run();
    });

    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
}

それが解決策になるかどうかはわかりませんが、より多くの UIThreads を要求しました;)

于 2014-02-12T05:38:58.687 に答える