グラフノードツリーに大きく依存するツールを作成しています。現在の実装はJavaで行われ、C#の汎用コードベースに移植しているので、さまざまなレンダリング実装で使用できます。また、ユーザーフレンドリーなインターフェイスのためのWPF。
1日ブラウジングした後、WPFを介してベクターグラフィックを描画するさまざまな方法に出会いました。
この男 WPF開発者が選択できるさまざまなレイヤーについて話します。最初はWPFPURELYを使ってレンダリングしたいので、「ビジュアルレイヤー」で作業したいと思います。
次に、次のようなものに出くわしました: DrawingVisual 、 GeometryDrawing 、 FrameworkElement / IElement /Shapes
ですから、私は、最終的にはまったく異なる方法で同じことを行うすべての異なる実装に少し圧倒されています。
Graph-Nodeライブラリは、すべてのロジック(衝突検出やマウスでのドラッグを含む)とともにすでにC#に移植されています。グラフィックレンダラー(XNA、SlimDX、OpenTKなど)を念頭に置いて作成されているため、パフォーマンスの観点からWPFレンダラーを実装するための最良の方法は何でしょうか(グラフライブラリが指示するものは何でも描画します)。描く?
基本的に、結果のWPFコントロールはキャンバスとして機能しますが、超軽量で、円、線、その他の形状を描画する方法を提供する以外に、きちんとしたWPF機能を備えていない必要があります:)
編集:
私は基本的に知りたいです:行く方法は何ですか?グラフィックの「ホスト」としてCanvasを拡張してから、UIElementのカスタム実装を追加しますか?または、すべてを描画できるクラスを1つ持つことはできますか(1つのメガスーパーウルトラグラフィックのように)。 GDIのOnPaintまたはJava(すべてを実行するためのGraphicsオブジェクトを提供する)のPaintメソッド)をオーバーライドするのとよく似ています。
読むことをお勧めします パフォーマンスの最適化:2Dグラフィックスとイメージング (リンク切れ-インターネットアーカイブ経由で読み取り可能)-
基本的に、Drawing
オブジェクトは一般的にShapes
よりも軽量になります。これはおそらくあなたが使いたいものです。
一般に、パフォーマンスは低レベルのサービスで得られます。 WPF
では、これはDrawing
ファミリーのオブジェクトを意味します。取得できるのは、Drawing
、DrawingGroup
、GeometryDrawing
、GlyphRunDrawing
、ImageDrawing
、およびVideoDrawing
だけです。ただし、すべてのニーズに十分対応できます。 Drawing
はWPFがGPUアクセラレータと交換する概念的な単位であり、可能であればそこで保持および管理するため、これらのタイプの使用はWPFと非常に便利です。これが機能するのは、Drawing
がポータブルベクトル描画プリミティブで表現されているためです。
ただし、Drawings
を中心にアプリの再設計を開始すると、UIElement
、FrameworkElement
などに基づいた高レベルのコードとの相互運用が必要になる場合があります。 WPFに組み込まれていることがわからないのは、図面をFrameworkElementとしてラップするを可能な限りオーバーヘッドの少ない方法で行う簡単な方法です。 DrawingVisual
はVisual
からのみ派生するため、完全なソリューションではありません。つまり、ホスティング要素が必要です。
次のクラスは、中間のDrawing
を使用せずに、任意のWPF DrawingVisual
を直接ホストします。 FrameworkElement
のMargin
プロパティのサポートを追加しました(未使用の場合はパフォーマンスの低下はありません)が、それ以外はほとんどありません。 WPFの単一のレンダリングスレッドにより、マージンを実装するために単一のTranslateTransformオブジェクトを安全かつ簡単にキャッシュできます。冷凍された図面のみを提供することをお勧めします。実際、私が使用しているバージョンでは、コンストラクターでその効果を表明しています。
public class DrawingElement : FrameworkElement
{
static readonly TranslateTransform tt_cache = new TranslateTransform();
public DrawingElement(Drawing drawing)
{
this.drawing = drawing;
}
readonly Drawing drawing;
TranslateTransform get_transform()
{
if (Margin.Left == 0 && Margin.Top == 0)
return null;
tt_cache.X = Margin.Left;
tt_cache.Y = Margin.Top;
return tt_cache;
}
protected override Size MeasureOverride(Size _)
{
var sz = drawing.Bounds.Size;
return new Size
{
Width = sz.Width + Margin.Left + Margin.Right,
Height = sz.Height + Margin.Top + Margin.Bottom,
};
}
protected override void OnRender(DrawingContext dc)
{
var tt = get_transform();
if (tt != null)
dc.PushTransform(tt);
dc.DrawDrawing(drawing);
if (tt != null)
dc.Pop();
}
};
[編集:]これは、WPF Drawing
をInlineUIContainer.Child
プロパティに挿入する場合にも役立ちます(つまり、TextBlock.InlinesCollection
を使用してTextBlockのコンテンツをより豊富にフォーマットします)。
drawingVisualは有効な選択のようです。
DrawingVisualは、図形、画像、またはテキストをレンダリングするために使用される軽量の描画クラスです。このクラスは、レイアウトやイベント処理を提供せず、パフォーマンスが向上するため、軽量と見なされます。このため、描画は背景やクリップアートに最適です。
だから、これは絶対にあなたが求めるもののようです、CanvasSUPER軽量。