4

私は最近、クリックアンドドラッグを使用して特定の形状を描画できるCanvasを備えた、会社用の描画コンポーネントを開発しました。シェイプごとに、2つのアドナーをAdornerLayerに配置しました。1つはヒット検出を増やすため(基本的にはシェイプの境界を数ピクセル超える透明な長方形)、もう1つはサイズ変更用(コーナーに4つのサムコントロール)です。

しかし、コンポーネントの機能のいくつかを実装するときに、すべての装飾者に関連する多くの問題に遭遇しました。

  • Canvas自体とは別のビジュアルツリーにあるため、すべてのプレビューイベントをキャプチャしました。これは予想外のことでしたが、あまり気に入らなくても回避策を見つけました。AdornerDecoratorを使用してもこの問題は解決しませんでした。実装した選択装飾は、プレビューイベントのブラックホールです。

  • Canvasに図形のz-index操作(後ろに送信、前に移動など)を実装したとき、期待どおり、Panel.SetZIndexを使用して正常に機能しました。しかし、装飾者は別のビジュアルツリーにいます!そのため、それらは影響を受けず、選択装飾者がヒットを検出していた形状の上にそれらの形状があったとしても、選択装飾者は他のすべての形状の上にまだありました。例:Shape1、SelectionAdorner1。Shape2、SelectionAdorner2。Shape1はShape2の上部(後でキャンバスに追加)にあるため、重なり合っています。したがって、それをクリックすると、SelectionAdorner1によって検出されます。ZIndexを操作して送り返しましたが、Shape2が一番上にあり、Shape1と重なっています。Shape2の上部をクリックしましたが、クリックはSelectionAdorner2ではなくSelectionAdorner1によって検出されます。これは特に厄介でした。それで、どうやらAdornersは別のビジュアルツリー上にあるため、ZIndexesを尊重していません。シェイプのZIndexとSelectionAdornerのZIndexの間にDataBindingを作成する(および手動で設定する)ことで、これを解決しようとしました。しかし、これは問題を解決しませんでした。AdornersのZIndexを変更しても、画面への表示方法には影響しませんでした。何かが足りなかったのかもしれませんが、Adornersは物事を簡単にするために作られているはずなので、それほど難しいことではありません。私が思いついた唯一の解決策は、すべての装飾者を手動で削除し、それらを1つずつ手動で再度追加し、最後に一番上にあるはずの装飾者を追加することでした。それは遅れましたが、うまくいきました。シェイプのZIndexとSelectionAdornerのZIndexの間にDataBindingを作成する(および手動で設定する)ことで、これを解決しようとしました。しかし、これは問題を解決しませんでした。AdornersのZIndexを変更しても、画面への表示方法には影響しませんでした。何かが足りなかったのかもしれませんが、Adornersは物事を簡単にするために作られているはずなので、それほど難しいことではありません。私が思いついた唯一の解決策は、すべての装飾者を手動で削除し、それらを1つずつ手動で再度追加し、最後に一番上にあるはずの装飾者を追加することでした。それは遅れましたが、うまくいきました。シェイプのZIndexとSelectionAdornerのZIndexの間にDataBindingを作成する(および手動で設定する)ことで、これを解決しようとしました。しかし、これは問題を解決しませんでした。AdornersのZIndexを変更しても、画面への表示方法には影響しませんでした。何かが足りなかったのかもしれませんが、Adornersは物事を簡単にするために作られているはずなので、それほど難しいことではありません。私が思いついた唯一の解決策は、すべての装飾者を手動で削除し、それらを1つずつ手動で再度追加し、最後に一番上にあるはずの装飾者を追加することでした。それは遅れましたが、うまくいきました。なぜなら、装飾者は物事を簡単にするために作られることになっているからです。私が思いついた唯一の解決策は、すべての装飾者を手動で削除し、それらを1つずつ手動で再度追加し、最後に一番上にあるはずの装飾者を追加することでした。それは遅れましたが、うまくいきました。なぜなら、装飾者は物事を簡単にするために作られることになっているからです。私が思いついた唯一の解決策は、すべての装飾者を手動で削除し、それらを1つずつ手動で再度追加し、最後に一番上にあるはずの装飾者を追加することでした。それは遅れましたが、うまくいきました。

  • 次に、AdornersはClipToBoundsを尊重しません!描画を行っていたキャンバスでClipToBounds=trueを設定しました。これは正常に機能しましたが、気の利いた装飾者は引き続き機能します。これに対する解決策は比較的簡単でした。各Shapeの上にAdornerDecoratorを追加しただけです。理想的なソリューションIMOではありませんが、十分に単純なソリューションです。

  • 装飾者は、装飾された要素に対して実行されるLayoutTransformsに常にうまく反応するとは限りません。キャンバスの上に、ズーム機能とパン機能を実装するパネルがあります。アニメーションを使用して、ズームインとズームアウトをよりスムーズにしました。しかし、アニメーションを使用すると、私の愛好家は猿になりました!最初のズームではサイズ変更を無視して同じサイズと位置を維持し、2番目のズームでは装飾された要素の前のサイズに拡大縮小します。それは意味がありませんでした!私が見つけた唯一の解決策は、アニメーションを無効にすることでした。これはありがたいことに機能しました

他にどのような問題があったかはよく覚えていませんが、これでAdornersの有用性について疑問に思うほどでした。次のプロジェクトでは、これを使用しないことを真剣に検討しています。これは、私が説明したものと似ています。 。

それで、これらの一見有用であるが信じられないほど迷惑なものを使用することの長所は何である可能性があるかを誰かに教えてもらえますか?

ありがとう。

4

1 に答える 1

8

あなたはすでにあなたの質問に対する答えを知っていると思います。それらはいくつかの面で時間を節約し、他の面では問題を引き起こします。さまざまなUserControlsを使用してこのデザイナーの動作をコーディングする場合、実際に編集したい要素をラップするために、多くの定型的なコントロールクラスを作成していることに気付くでしょう。一方、個別の編集コントロールを作成してインテリジェントにオーバーレイしようとした場合は、位置とサイズの同期を維持するための定型コードを作成することになります。装飾者を使用して採用したアプローチでは、イベントを管理するための多くの(かなり定型的な)コードが作成されました。

装飾者はこの特定のタスクに最適なツールではないかもしれませんが、それでも他のより単純なタスクには便利なツールです。私は最近、同様の種類の「デザインサーフェス」を作成しましたが、装飾者は2つの作品の天の恵みでした。

  1. ドラッグアンドドロップの動作。さまざまな要素をドラッグしたとき、それらはさまざまな視覚的プレビューを持つ必要がありました。これは、カスタム装飾とデータテンプレートを使用して非常に簡単に実行できました。
  2. 選択長方形または「なげなわ」。Windowsデスクトップでマウスの左ボタンを押したまま、ポインタをドラッグすると、似たようなものが表示されます。複数の要素を選択できる半透明のボックスを作成します。アドナーレイヤーを使用してこの動作をほぼ瞬時に作成できましたが、独自のカスタムコントロールを作成すると、多くの不要な簿記が作成されました。

あなたがあなたのプロジェクトで発見したことは、あなたがあまりにも多くのことを成し遂げるために装飾者を使っていたかもしれないということだと思います。しかし、お風呂の水で赤ちゃんを捨てないでください-彼らはまだ特定のシナリオで非常に便利です。

于 2011-06-14T01:43:41.853 に答える