1

100以上の異なるフォントでサンプルテキストを表示するグリッドを含むWindows8XAMLページがあります。サンプルテキストは各グリッドビューアイテムで同じであり、ページ上部のテキストボックスを使用して変更できます。

文字を入力するたびに、すべてのグリッドビューアイテムが更新されます。問題は、これが著しく遅いことです。特にすばやく入力する場合。

何がそんなに遅くなっているのかわかりません。画面に表示されていないものも含め、すべてのグリッドビューアイテムを更新していますか?他の何かが問題を引き起こしていて、この特定のバインディングは単なる赤いニシンですか?

これが私のバインディングコードです(明確にするためにデータテンプレートからいくつかのxamlを削除しました):

<ScrollViewer>
    <GridView x:Name="FontGridView" ItemsSource="{Binding Fonts}" SelectionMode="Multiple"  Margin="116,0,40,46">
        <GridView.ItemTemplate>
            <DataTemplate>
                <Grid Width="600" MinHeight="100" MaxHeight="120">
                    <TextBox Text="{Binding ElementName=pageRoot, Path=DataContext.SampleText, Mode=OneWay}"
                                FontFamily="{Binding FamilyName}" FontSize="32" Background="Transparent" />
                </Grid>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>
</ScrollViewer>

これを行うためのより良い方法はありますか、または私がオンにできる他のパフォーマンス調整機能はありますか?

更新: Visual Studio 2012 RCがリリースされて以来、この間違いを犯す可能性は低くなっています。WinRTアプリのテンプレートは、この方法でScrollViewerを使用しなくなりました。Visual Studio 2011を使用して作成したアプリを移植した人のために、ここで質問を続けています。

4

3 に答える 3

2

ScrollViewerを削除してみてください。

GridViewはscrollviewer内にあるため、事実上無限の幅が与えられます。これにより、GridViewでのWrapGridの仮想化が停止する可能性があります。

さらに、GridViewにはすでにScrollViewerが内部に含まれています。明らかに、それらのうちの2つは必要ありません。ただし、内側のScrollViewerはマウスホイールイベントも消費し、外側のScrollViewerが反応するイベントは残しません。その結果、マウスでのスクロールは機能しません。

Visual Studio 11(bèta1)テンプレートには、GridViewにマージンを設定するためのこのようなコードが含まれています。ただし、次のように、GridViewのItemsPanelにマージンを設定することをお勧めします。

<GridView x:Name="FontGridView" ItemsSource="{Binding Fonts}" SelectionMode="Multiple">
  <GridView.ItemTemplate>
    <DataTemplate>
      <Grid Width="600" MinHeight="100" MaxHeight="120">
        <TextBox Text="{Binding ElementName=pageRoot, Path=DataContext.SampleText, Mode=OneWay}"
                 FontFamily="{Binding FamilyName}" FontSize="32" Background="Transparent" />
      </Grid>
    </DataTemplate>
  </GridView.ItemTemplate>
  <GridView.ItemsPanel>
    <ItemsPanelTemplate>
      <WrapGrid x:Name="itemGridViewPanel" Margin="116,53,116,46"/>
    </ItemsPanelTemplate>
  </GridView.ItemsPanel>
</GridView>

元のコードには、GridViewで設定したマージンが含まれていませんでした。しかし、それが何であれ、WrapGridに同じマージンを設定します。

WrapGridに名前を付けたことにも注意してください。通常、次のように、その名前を使用して、画面の向きが変わったときにマージンを変更できます。

<VisualStateManager.VisualStateGroups>
  <VisualStateGroup>
    <VisualState x:Name="FullScreenLandscape"/>
    <VisualState x:Name="Filled"/>
    <VisualState x:Name="FullScreenPortrait">
      <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridViewPanel"
                                       Storyboard.TargetProperty="Margin">
          <DiscreteObjectKeyFrame KeyTime="0" 
                                  Value="96,53,96,46"/>
        </ObjectAnimationUsingKeyFrames>
      </Storyboard>
    </VisualState>
    <VisualState x:Name="Snapped"/>
  </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

アップデート:

私は以前にこれを行いましたが、VariableSizedWrapGridを使用しました。これにより正しいレイアウトが生成されますが、残念ながら、VariableSizedWrapGridは仮想化パネルではありません。

WrapGridは仮想化されていますが、スクロール時の左マージンの動作が間違っているようです。ただし、右マージンでは正しいです。

そうですね、2週間以内に、リリース候補が利用可能になるはずです。うまくいけば、物事は改善されるでしょう...

アップデート:

Microsoftはこれを認識しているようです。http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/17385f7d-aadc-4edc-bbff-8738a2f0c917を参照してください。

アップデート:

WrapGridはリリース候補で修正されていないようです。

于 2012-05-25T23:51:08.940 に答える
1

データテンプレートを簡素化します。

<DataTemplate>
  <TextBlock Text="{Binding ElementName=pageRoot, Path=DataContext.SampleText}"
             Width="600" MinHeight="100" MaxHeight="120"
             FontFamily="{Binding FamilyName}" FontSize="32" />
</DataTemplate>

グリッドは必要ありません。また、(複雑な)TextBoxも必要なく、(単純な)TextBlockだけが必要なようです。

また、これらのテキストブロックの高さ(Height="120")を修正すると、レイアウトプロセスが役立つ(最適化される)場合があります。

アップデート:

あなたのコードは「本物」から単純化されていると思います。しかし、それは私たちにとって本当の問題を隠すかもしれません。データテンプレートは、画面に表示されているすべてのアイテムに対してインスタンス化されていることを忘れないでください。複雑になるほど、より多くのオブジェクトをインスタンス化する必要があり(CPUとメモリの使用量)、場合によってはデータバインド(CPU)、測定とレイアウト(CPU)、レンダリング(CPUとGPU)が必要になります。

非常に単純なデータテンプレートを使用してテストを実行するだけです。プログラムが今より高速であるかどうかにかかわらず、データテンプレートがパフォーマンスの問題であるかどうかがわかります。

データテンプレートの複雑さは、説明する必要のあるxaml要素の数では測定されないことに注意してください。これらの要素は、内部の複雑さが大きく異なる可能性があるためです。たとえば、編集を許可せずにテキストを表示するだけの場合は、TextBoxよりもTextBlockを優先します。

また、これらの要素の一部に多くのプロパティが設定されている場合は、スタイルを使用して設定してください。多くのオブジェクトにスタイルを使用する方が、特にメモリ使用量に関しては、多くのオブジェクトに多くのプロパティを設定するよりも効率的です。また、使用するメモリが少ないほど、プログラムは高速になります(最新のCPUマルチレベルキャッシングアーキテクチャにより)。

例えば:

<GridView x:Name="FontGridView" ItemsSource="{Binding Fonts}" SelectionMode="Multiple">
  <GridView.Resources>
    <Style TargetType="TextBlock">
      <Setter Property="Width" Value="600" />
      <Setter Property="MinHeight" Value="100" />
      <Setter Property="MaxHeight" Value="120" />
      <Setter Property="FontSize" Value="32" />
    </Style>
  </GridView.Resources>
  <GridView.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding ElementName=pageRoot, Path=DataContext.SampleText}"
                 FontFamily="{Binding FamilyName}" />
    </DataTemplate>
  </GridView.ItemTemplate>
</GridView>
于 2012-05-25T19:23:49.037 に答える
0

VirtualizingStackPanelを使用してみてください

<GridView.ItemsPanel>
    <ItemsPanelTemplate>
        <VirtualizingStackPanel Orientation="Horizontal"/>
    </ItemsPanelTemplate>
</GridView.ItemsPanel>
于 2012-05-25T17:30:30.580 に答える