0

線などのベクター プリミティブを描画するための Windows Forms C# アプリケーションを作成しました。楕円など。選択した図形の境界線の幅を変更する方法があります。これは方法です:

   public void SetBorderWidth(int border)
    {
        if (border < 0) 
            return;

        if ((SelectedItem != null) && (SelectedItem.isGroup == false)) 
        {              
            SelectedItem.BorderWidth = border;
        }

        if ((SelectedItem != null) && (SelectedItem.isGroup == true))
        {

            ChangeCascadeBorderWidth(SelectedItem, border);
        }

        foreach (Shape figure in ObjectsDrawn)
        {
            if (figure.Selected)
            {
                ObjectsDrawn[ObjectsDrawn.IndexOf(figure)].BorderWidth = border;
            }

            if (figure.isGroup)
            {
                ChangeCascadeBorderWidth(figure, border);
            }
        }            
    }

メソッドを呼び出す人:

    private void ChangeCascadeBorderWidth(Shape group, int width)
    {
        foreach (Shape item in ((Grouping)group).GroupedElements)
        {
            if (item.isGroup == true)
            {
                ChangeCascadeBorderWidth(item, width);
            }
            else
            {
                item.BorderWidth = width;
            }
        }
    }

図形が複数の図形のグループである場合。しかし、これは動作が遅すぎます。1 つまたは複数の図形を選択した場合でも、10 ~ 15 秒待たなければならないことがあります。境界線の幅を変更します。なぜそんなに遅いのですか?

4

3 に答える 3

0

あなたが投稿したすべてのボトルネックは、シェイプに BorderWidth プロパティを設定しているようです。BorderWidth の形状のレイアウトを再描画または更新していると思います。コンテナーに BorderWidth を設定すると、多くの不要な再描画とレイアウトの変更が発生し、WinForms では少し遅くなります (特にレイアウトの場合、形状が Control から継承されている場合)。

他の WinForms コントロールと同様に、 BeginUpdate *EndUpdate* メカニズムを提案できますか?

于 2012-09-02T15:37:59.153 に答える
0

あなたのコードは、SelectedItem の境界線、Selected プロパティが true に設定されている ObjectDrawn、およびグループに属する描画されたすべてのオブジェクトの境界線を編集しています。

グループの図形が選択されているかどうかにも基づいて、グループの境界線の描画をフィルター処理するつもりでしたか?
figure.isGroup && figure.Selected そうしないと、すべてのグループの境界が変更されるように思われます。グループが多数ある場合、選択した内容に関係なく、パフォーマンスの問題が発生する可能性があります。

追加のパフォーマンス改善の提案: SetBorderWidth でこれを行います
:
ObjectsDrawn[ObjectsDrawn.IndexOf(figure)].BorderWidth = border; しかし、ChangeCascadeBorderWidth でこれを行います: item.BorderWidth = width; SetBorderWidth 関数で同じことを行うことをお勧めします。変更したいオブジェクトのインスタンスが既にあるため、IndexOf ルックアップは表示されません。必要。

また、BorderWidth プロパティを設定するコストが高い場合 (同じ既存の値に設定する場合でも)、次のように SetBorderWidth への呼び出しをラップ if(item.BorderWidth != width) item.BorderWidth = width;します。パフォーマンスを節約できます。ただし、境界線の幅を設定するコストに対する比較のコストを評価する必要があります。

于 2012-09-02T10:04:54.827 に答える
0

私の考え:

線ベースのプリミティブを使用して境界線をレンダリングできるため、幅が 1 ピクセルの場合、パフォーマンスが向上します。

1 より大きい幅を使用している場合は、塗りつぶされたプリミティブを使用する必要がありますが、これは遅くなります。

于 2012-09-02T09:48:46.317 に答える