実行時に動的に(カプセル化された)子供を作成するWPF要素
-
29-09-2019 - |
質問
実行時に、その子供の要素を完全に制御しているWPF要素を作成したいと思います。その特性が変更されたときに子のUIを追加および削除します。私の場合は1人の子供しかいないが、ItemsControlが項目Sourceプロパティを変更したときに行うことのようなこと。
これはMVVMのビューコンテナになります - モデルまたはビューモデルを提供すると、魔法のように正しいビューを作成し、すべてを配線します。私のビューコンテナはテンプレート可能である必要はありません(ユーザー定義のビューを作成し、それはユーザーカントロールであり、独自のテンプレートを持っているためです)。可能な限りカプセル化することを好む。おそらく、グリッドのようなものから降りて、自分のプロパティが変更されたときに子供のコントロールを追加することで、これを簡単に行うことができます。しかし、Gridは子どもの要素のコレクションを公開し、誰もが物を追加して削除できるようにします。
最大のカプセル化のためにどのWPFクラスから降りる必要がありますか?実行時に子要素を追加するにはどうすればよいですか?
ドキュメントの理解に基づいて、実行時に子供のコントロールを作成できるかどうかを確認するために、FrameworkElementとAddVisualChildを使用してみました。 AddLogicalChildが必要かどうかは明確ではありませんが、念のためにそれを入れました。
public class ViewContainer : FrameworkElement {
private TextBlock _child;
public ViewContainer() {
_child = new TextBlock { Text = "ViewContainer" };
AddLogicalChild(_child);
AddVisualChild(_child);
InvalidateMeasure();
}
public object Content { get; set; }
protected override Size ArrangeOverride(Size finalSize) {
_child.Arrange(new Rect(finalSize));
return finalSize;
}
protected override Size MeasureOverride(Size availableSize) {
_child.Measure(availableSize);
return _child.DesiredSize;
}
}
WindowにViewContainerを入れてこれを実行すると、「ViewContainer」というテキストブロックが表示されることを期待しています。しかし、代わりに、空白の窓が見えます。だから明らかに私は何かが足りない。
上記のコードを修正して、「子」コントロールが実行時に表示されるようにするにはどうすればよいですか?
解決
特定の質問に答えるには、オーバーライドする必要があります GetVisualChild と VisualChildRencount お子様要素を表示できるようにするプロパティ。
他のヒント
暗黙的なデータセテンプのWPFのサポートを利用することを考えましたか?
私があなたのものと同様の要件を処理した方法は、 ContentControl
. 。私はバインドします Content
私のviewmodelへのプロパティ。次に、コンテンツコントロールの上のツリーのどこかに参照されるリソース辞書で、コンテンツプロパティに割り当てられる可能性のあるすべてのタイプのビューモデルに対して定義されているデータセテンプラテを持っていることを確認します。
このように、WPFは私のViewModelの正しいビューを配線することになります。