0

仮想化を有効にして作成ListBoxし、すべてのアイテムの外観を更新すると、非常に高速に動作します。しかし、すべてのアイテムをゆっくりと下にスクロールしてListBoxから、すべてのアイテムの外観を更新すると、多くの時間がかかります。VirtualizingStackPanelビューポートを使い果たしたときにアイテムを破壊しないためだと思います。この動作を再現する簡単なアプリを作成しました。

コード:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        for(int i = 0; i < 5000; ++i) // creating 5k text boxes
            MyList.Items.Add(new TextBox() { Text = CurrText });
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        GC.Collect();
        n = (n + 1) % 2; // switch 0 to 1 or 1 to 0
        foreach (var item in MyList.Items)
            ((TextBox)item).Text = CurrText; // set new text
    }

    static int n = 0;
    string CurrText { get { return new string(n.ToString()[0], 50); } }
}

XAML:

<Window x:Class="VPanel.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="700" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="5*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ListBox Name="MyList" VirtualizingStackPanel.IsVirtualizing="True"/>
        <Button Grid.Row="1" Content="UpdateText" Click="Button_Click"/>
    </Grid>
</Window>

「UpdateText」ボタンをクリックすると、すべてのテキストボックスのテキストが更新されます。スクローラーをドラッグして最後までゆっくりスクロールすると、「UpdateText」ボタンのクリックが非常に遅くなります。

4

1 に答える 1

0

TextBoxes手動で作成しないでください。

「仮想化」という言葉は、ユーザー インターフェイス (UI) 要素のサブセットが、画面上に表示される項目に基づいて多数のデータ項目から生成される手法を指します。画面に少数の要素しか表示されない場合に多くの UI 要素を生成すると、アプリケーションのパフォーマンスに悪影響を及ぼす可能性があります

UI 項目を手動で作成するため、仮想化には既に遅すぎます。バインディングを使用すると、必要なときにいつでも作成TextBoxされItemTemplateます。TextBox.Text現在ビューにない場合、値も更新されません。それを行うには、代わりにMainWindow作成して操作するように変更します。ObservableCollectionTextBoxes

public partial class MainWindow : Window
{
    private readonly ObservableCollection<string> _textBoxes = new ObservableCollection<string>();

    public ICollection<string> TextBoxes { get { return _textBoxes; } }

    private int n = 0;
    private string CurrText { get { return new string(n.ToString()[0], 50); } }

    public MainWindow()
    {
        for (int i = 0; i < 5000; ++i) _textBoxes.Add(CurrText);
        InitializeComponent();
        DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        n = (n + 1) % 2; // switch 0 to 1 or 1 to 0
        for (int i = 0; i < _textBoxes.Count; i++) _textBoxes[i] = CurrText;
    }
}

TextBoxes次に、XAML を変更してlist プロパティにバインドします

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="5*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <ListBox ItemsSource="{Binding TextBoxes}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Path=., Mode=TwoWay}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button Grid.Row="1" Content="UpdateText" Click="Button_Click"/>
</Grid>
于 2014-05-10T09:31:42.837 に答える