1

私は、多数の DependencyProperties を持つ一連のコントロールに取り組んでいます。プロパティはそれ自体が DependencyObject であり、プロパティの get メソッドで作成されます。Get メソッドの間、これらは SetValue() メソッドを使用してプロパティバッグにも設定されるため、実際には Xaml で有効であり、それらのプロパティはビジュアル ツリーで明示的に作成しなくてもストーリーボードに入れることができます。

これらの DependencyObjects には、DataBinding をサポートするために、すべてのプロパティが DependencyProperties としても含まれています。上記のように、ストーリーボードで使用できます。

同時に、これらのプロパティに対する Blend 3 の特別なデザインタイム サポートを開発しており、コントロールの形式で InlineEditorTemplate を作成しました。テンプレートを作成し、次のように PropertyValueEditor に設定します。

        var vectorEditControl = new FrameworkElementFactory(typeof (VectorEditorControl));
        var dataTemplate = new DataTemplate {VisualTree = vectorEditControl};
        InlineEditorTemplate = dataTemplate;

コントロールには次のものがあります。

<Grid DataContext="{Binding Value}">

<StackPanel Orientation="Horizontal">
  <TextBox Text="{Binding Path=X, Mode=TwoWay}"/>
    <TextBox Text="{Binding Path=Y, Mode=TwoWay}"/>
    <TextBox Text="{Binding Path=Z, Mode=TwoWay}"/>
</StackPanel>

</Grid>

エディターが表示され、データを編集できます。デバッグ中も、データが DependencyObjects の DependencyProperties に実際に設定されていることがわかりますが、Xaml には何も起こりません。そのため、データは実際には Xaml に永続化されず、Xaml ファイルを閉じて再度開くと失われます。

実際に Xaml に入るために特に必要なことはありますか? 私はこれが自動的に起こるだろうという印象を受けましたか?

4

2 に答える 2

1

素晴らしい質問です!

Blend/Cider の PropertyEditor が最終的にデータバインディングを行うものについて、誤解に陥っている中心的な問題です。

次のオブジェクト グラフを考えてみましょう:
- MyControl
-- MyControl.MyProperty
--- FooClass
---- FooClass.BarProperty

プロパティ MyControl.MyProperty への PropertyEditor (任意のタイプ: インライン、ダイアログ、または拡張) があるシナリオを見てみましょう。MyPropertyPropertyEditor の内部では、完全に設定可能な FooClass のコピーを取得し、そのメンバーを操作できることが期待されます。それは良い仮定ですが、間違っています。

中心的な問題は、設計時に Blend/Cider がモデルを表す精巧なデータ構造を持っていることです。Blend/Cider が実際のコントロールと対話する方法には、約 3 ~ 5 レベルの抽象化があります。
これらのレベルの抽象化を作成することで、Expression Blend / Visual Studio デザイナーをフレームワーク (Silverlight / WPF) 間で活用し、高度なシナリオ (プロパティ トランザクションやプロパティ チェーンなど) をサポートできます。

したがって、実際に DataBind に取得する値は、それらの抽象化レベルの 1 つにすぎません。
信じられない?カスタム PropertyEditor で、this.DataContextChanged イベントに登録し、this.DataContext のタイプをチェックアウトします。PropertyValueクラス (またはその仲間の 1 つ) を取得することになります。

XAML に保持する (およびデザイン サーフェイスに表示する) 必要があるすべてのプロパティの変更は、これらの抽象化レイヤーを通過する必要があります。

自問しなければならない質問は、「PropertyValue.Value プロパティ インスタンスのこれらの抽象化クラスの 1 つをどこで取得できるか」です。

私があなただったら、MyControl.MyProperty の周りに ModelItem を作成し、それを PropertyEditor.DataContext として設定します。Chart DefaultInitializer: Source Codeの一部として、Silverlight Toolkit で ModelFactory.CreateItem を使用する例を出荷しました。Ning Zhang (Awesome Design Time Dev) が ModelItem について説明しています。

フォローアップの質問がある場合は、Silverlight Insider メーリング リストから PeteBl または UnniR に問い合わせることを検討します。


--ジャスティン

于 2009-11-25T13:14:14.360 に答える
0

それは私の問題を部分的に解決します。フォローアップのために UnniR と対話を行っています。これを PropertyValueEditor と一緒に使用する方法がわかりませんでしたが、デフォルト値の場合、これは素晴らしいので、できるだけ早く実装します。

ありがとう。

于 2009-11-27T18:11:59.667 に答える