0

アプリの1つをWPFに変換することを考えていますが、主な懸念事項の1つは、DataGridコントロールのパフォーマンスでした(ユーザーのコンピューターは、専用のグラフィックを備えていない古いXPマシンです)。私は数千行を試しましたが、スクロールのパフォーマンスはひどいものでした。

FrameworkElementデータグリッドセルのコンテンツを、 ?から派生したカスタムクラスに設定する方法があるかどうか疑問に思いました。

仮想化スタックパネルに配置すると、パフォーマンスが大幅に向上するように見えるサンプルクラスを次に示します。

public class LiteTextBlock : FrameworkElement
{
    private Size _mySize;
    private string _myText;
    private double totalWidth;
    private GlyphTypeface _typeface;
    private int _fontSize;
    private GlyphRun _run;

    public LiteTextBlock(Size mySize, string myText, GlyphTypeface typeface, int fontSize)
    {
        _mySize = mySize;
        this.Width = _mySize.Width;
        this.Height = _mySize.Height;
        _myText = myText + " additional information";
        _typeface = typeface;
        _fontSize = fontSize;
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        if (_run == null)
        {
            totalWidth = 0;

            ushort[] glyphIndexes = new ushort[_myText.Length];
            double[] advanceWidths = new double[_myText.Length];

            for (int i = 0; i < _myText.Length; i++)
            {
                ushort glyphIndex = _typeface.CharacterToGlyphMap[_myText[i]];
                double width = _typeface.AdvanceWidths[glyphIndex] * _fontSize;

                if (totalWidth + width >= _mySize.Width - 10)
                {
                    Array.Resize(ref glyphIndexes, i);
                    Array.Resize(ref advanceWidths, i);
                    break;
                }

                glyphIndexes[i] = glyphIndex;
                advanceWidths[i] = width;
                totalWidth += width;
            }

            Point origin = new Point(5, 0);

            _run = new GlyphRun(_typeface, 0, false, _fontSize, glyphIndexes
                , origin, advanceWidths, null, null, null, null, null, null);
        }

        drawingContext.DrawGlyphRun(Brushes.Black, _run);
    }
}

これが可能かどうか誰かに見せてもらえますか?

免責事項:私はすでに、などの軽量のコントロールを使用しようとしましたListViewが、パフォーマンスはまだ劣っていました。

4

3 に答える 3

1

はい、方法があります。

カスタムDataGridColumnを実装し、そのGenerateElementメソッドをオーバーライドする必要があります。また、 DataGrid.AutoGeneratingColumnイベントを処理して、カスタムDataGridColumnをDataGridに設定する必要があります。

カスタムDataGridColumnのサンプルを次に示します。

public class DataGridLiteTextColumn : DataGridColumn
{
    private readonly PropertyDescriptor property;

    private readonly GlyphTypeface glyphTypeface = new GlyphTypeface(new Uri("file:///C:\\WINDOWS\\Fonts\\Arial.ttf"));

    public DataGridLiteTextColumn(PropertyDescriptor property)
    {
        this.property = property;
    }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        var value = property.GetValue(dataItem);
        return new LiteTextBlock(new Size(100, 20), value != null ? value.ToString() : string.Empty, this.glyphTypeface, 10);
    }

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
        throw new NotImplementedException();
    }
}

DataGrid.AutoGeneratingColumnイベントのハンドラーは次のとおりです。

private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    e.Column = new DataGridLiteTextColumn((PropertyDescriptor)e.PropertyDescriptor);
}

このコードは値を表示するために機能しますが、LiteTextBlockコンストラクターのサイズパラメーターはおそらく適切な値に設定されていません。値を編​​集するには、 GenerateEditingElementメソッドも実装する必要があります。

于 2012-10-01T19:19:55.760 に答える
0

DataGridのEnableRowVirtualizationプロパティがTrueに設定されていることを確認してください。デフォルトではTrueである必要がありますが、スタイルのどこかでFalseに設定されていないことを確認してください。

于 2012-10-01T14:41:55.153 に答える
0

UI Virtualizationデフォルトで有効になっています。ただし、次のいずれかのシナリオで無効になります-

  1. DataGridは、メジャーアレンジプロセス中に無制限の高さを持ちます。DataGridがすべてのアイテムを配置するのに十分なスペースがあると判断した場合、DataGridは何も仮想化しません。これは通常、DataGridをスタックパネルに配置したときに発生します。

  2. データグリッドのItemsPanel。仮想化は、VirtualizingStackPanelによって実現されます。ItemsPanelを変更すると、VirtualizingStackPanelは削除されます。

  3. アイテムのグループ化。.NET4.0では、仮想化はグループ化をサポートしていません。場合によっては、GroupStyleをDataGridに割り当てると、アイテムがグループ化されていなくても仮想化がオフになります。

上記のいずれのシナリオにも該当しないことを確認してください。

Data Virtualization補足として、データグリッドのアイテムソースに実装することもできます。証明付きの同じサンプルはここにあります-データ仮想化

于 2012-10-01T17:41:41.997 に答える