2

ドッキング コントロール (Actipro) を使用する WPF アプリケーション (.Net 4.0) があります。ドッキング ウィンドウをドッキングできます。その場合、「実際の」ウィンドウが作成され、コンテンツがそのウィンドウに割り当てられます。

もちろん、ビジュアル ツリー内のものを移動すると、完全なレイアウトが再トリガーされます。これらのドッキング ウィンドウの 1 つに、ダイアグラム コントロール (Mindfusion Diagramming、WPF コントロール) があるため、これは問題です。

この問題に対する直接的な解決策はないと思います。しかし、同様の問題を抱えている他のプログラマーがこの問題にどのように取り組んだのだろうか。レイアウトの再計算を回避する賢い方法はありますか?

理論的には、ダイアグラムは ScrollViewer 内にあるため、実際には何も変化しないため、配置されるたびに、使用可能なスペースの量は同じ (無限) のままです。

編集: 内部のダイアグラム コントロールがインタラクティブであることにも注意してください。ドラッグ&ドロップが必要です。

4

3 に答える 3

4

ここにアイデアがあります。

  1. Decorator を継承するカスタム クラスを作成します。
  2. デコレータ内にダイアグラム コントロールをラップします。
  3. MeasureOverride をオーバーライドし、単純に base.Measure を呼び出しますが、結果を返す前にフィールドに格納します。
  4. 測定呼び出しを無効にできるプロパティを追加します。プロパティが true の場合、base.Measure を呼び出す代わりに、MeasureOverride で以前のサイズを返すだけです。
  5. ビジュアル階層を変更しながらプロパティを設定します。

私の頭の上から、これがうまくいかない理由は考えられません。

私は実際に非常に似たようなことを少し前に行ったことがあります。NovaMindでサイド パネルのスライド アニメーションを実装するとき、Decorator を使用して、パネルが幅をアニメーション化する間、コンテンツがレイアウトを実行しないようにしました。最終的な幅でサイズを計算し、それを保存してから、MeasureOverride を使用して現在のサイズを偽造しました...これにより、複雑なコントロールの幅をアニメーション化しようとしたときに発生するパフォーマンスの問題が回避されました。:)

于 2010-10-28T01:48:29.167 に答える
1

もう 1 つの可能性は、問題がレイアウトに関連しているのではなく、あるウィンドウから別のウィンドウにコンテンツを移動するときのビジュアル ツリーの "切断" であるということです。これにより、依存関係プロパティの大量の再計算が発生するようです。コンテンツのビジュアル ツリーが私のようで、2000 以上のコントロールである場合、非常に遅くなります。

Actipro ドッキング ライブラリ自体を使用してこれに対するエレガントな解決策を見つけることができなかったため、WPF がこの動作を実行するのを回避する方法を考えました。私が思いついた解決策は、WinForms UserControl の単一の子を持つ単一の WinFormsHost コントロールとしてコンテンツを作成することでした。次に、WinForms UserControl のコンテンツが、ドッキング ウィンドウのコンテンツとして表示される WPF ベースのコンテンツになるようにしました。ツリーが「切り取られた」ときに、WPF がビジュアル ツリーを上から見てすべての依存関係プロパティを再評価し始めると、WinForms コントロールにぶつかって停止することがわかりました。

私の Actipro ドッキング ツール ウィンドウは、タブの切り替えやフロートに 6 秒ほどかかっていました。現在、それらは本質的に瞬時です。コマンド ハンドラーがアプリケーション レベルではなく、WPF コンテンツ レベルであることを確認する必要があり、いくつかのスタイル ファイルの場所を確認する必要があるかもしれませんが、うまくいきました。

于 2013-01-28T15:12:55.063 に答える
0

ビジュアル ツリーのダイアグラム コントロールをイメージに置き換え、オフスクリーン ダイアグラムをレンダリングし、rendertargetbitmap を使用してレンダリングされたダイアグラムをイメージに変換し、ビジュアル ツリーのイメージのソースとして使用することができます。

このようなもの:

// image is the Image from the visual tree
int h = image.ActualHeight;
int w = image.ActualWidth;

// layout the diagram to the size of the image
diagram.Measure(new Size(w, h));
diagram.Arrange(new Rect(newSize(w,h)));
diagram.UpdateLayout();

// render the diagram to a bitmap
RenderTargetBitmap bmp = new RenderTargetBitmap((int)w, (int)h, 96, 96, PixelFormats.Default);
bmp.Render(diagram);

// set the source of your image to the bitmap
image.Source = bmp;

この例では、PixelFormats.Default が機能しないように思われる場合は、PixelFormats.Pbgra32 を試すことができます。これは、この種のもので使用するより一般的な形式だと思います。

同様の方法で VisualBrush を使用することもできます。長期的には、図のラッパー クラスを作成して、画像のコピーを自動的に表示し、何かが変更された場合 (つまり、図の一部またはサイズ) にのみ図を再レイアウトできると想像できます。

于 2010-10-19T17:05:59.060 に答える