シェイプにscaletransformを適用するときに、誰かがWPFシェイプレンダリングのデフォルトの動作をオーバーライドできたかどうか疑問に思っています。デフォルトの動作では、ストロークを含む形状描画全体が変換されますが、ジオメトリを拡大縮小したいだけです。難しいのは、私のシェイプがさまざまなレベルでレンダリング変換が適用されたビジュアル階層に存在することです(2Dシーングラフのようなものですが、WPFビジュアルツリーのようなものです)。これは変更できません(!)。さまざまな場所で、カスタムシェイプを作成して、レンダートランスフォームのトランスフォームをキャンセルし、代わりにジオメトリに配置できる可能性があることを読みました。現在、私は次のようなものを持っています:
public sealed class MyPath : Shape
{
// This class has a Data property of type Geometry just like the normal Path class
protected override Geometry DefiningGeometry
{
get
{
Geometry data = Data;
if (data == null)
{
data = Geometry.Empty;
}
return data;
}
}
protected override void OnRender(DrawingContext drawingContext)
{
Transform tr = RenderedGeometry.Transform;
Geometry geomToDraw = RenderedGeometry.Clone();
geomToDraw.Transform = new MatrixTransform(tr.Value * tr.Value);
Matrix trInv = tr.Value; trInv.Invert();
drawingContext.PushTransform(new MatrixTransform(trInv));
drawingContext.DrawGeometry(Brushes.Transparent, new Pen() { Brush = Brushes.Black, Thickness = 1 }, geomToDraw);
}
}
明らかに明らかなように、私はこれにまったく慣れておらず、上記のコードはおそらく完全に台無しになっています。最終的に得られるジオメトリ変換、つまりtr.Value * tr.ValueとtrInvを変更せずに、マトリックスをジオメトリに転送しようとしました。しかし、私が望むようには機能しません。定数変換で試してみたので、この転送変換手法が理論的に機能することはわかっています(Geometry.Transformを4でxをスケーリングし、0.25でxをスケールするように変換をプッシュすることは問題なく機能しましたが、結果の形状描画は適用されなかったようです。 Stretch = fill、私はこれに依存しています)。したがって、レンダリング変換で欠けているものがあるはずです。
動作していないテストシナリオは次のとおりです。
- xamlでscaleX=4およびscaleY=1のレンダリングスケール変換を適用します。
- 組み込みのPathクラスは、y方向よりもx方向のストロークが4倍になるように、図面全体を拡大縮小します。
- MyPathで、ストロークではなく、ジオメトリのみをスケーリングする必要があります。<-これは機能していません!
- 何が起こるか:ジオメトリは正しくスケーリングされ、ストロークはx方向に4だけスケーリングされ、y方向に4よりわずかに小さくなります。なにが問題ですか?RenderedGeometry.Transformだけで作業するべきではないと感じていますが、代わりに何を使用すればよいですか?シェイプにレンダートランスフォームとstretch=fillを組み込む必要があります。私のレンダートランスフォーム階層には、スケール、回転、平行移動が混在している可能性があるため、ソリューションは、軸に沿ったスケーリングだけでなく、あらゆるトランスフォームを処理するのに十分一般的である必要があります。
注:OnRenderでジオメトリを作成するのは悪いことですが、クリーンアップに時間を費やす前に、ジオメトリを機能させたいと思っています。
ちなみに、私はこの投稿を読みました:
前に述べた問題は、レンダリング変換を考慮に入れる必要があり、それらを使用するためにそのソリューションをどのように適応させるかがわからないことです。