12

XAML から依存関係プロパティを設定しようとしています。依存関係プロパティは、IEnumerable<KeyAction>KeyAction が複合型である場所です。

<loc:MyType.KeyActions>
    <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" />
    <loc:KeyAction Action="Hide" Key="Escape" />
</loc:MyType.KeyActions>

これにより、KeyActionXAML は各項目をリスト内の項目ではなく、プロパティの候補として解釈するため、プロパティが「2 回宣言」されます。

これが機能するには、次のようにする必要があります。

<loc:CompletionPopupView.KeyActions>
    <sys:List`KeyAction>
        <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" />
        <loc:KeyAction Action="Hide" Key="Escape" />
    </sys:List`KeyAction>
</loc:CompletionPopupView.KeyActions>

そして、名前空間を追加する必要があり、一般的な構文は、実行可能であったとしても、おそらくさらにひどいものです。最初の例を機能させる方法はありますか?

4

1 に答える 1

24

これを機能させるには、2 つの異なる方法があります。最初の例とまったく同じように見えますが、クラスを変更する必要があり、要求どおりに動作しません (問題になる場合とそうでない場合があります)。他のものはあなたが求めているのとまったく同じように機能しますが、もう少し冗長です。どちらがあなたにとってより良いかを決めることができます。

オプション 1: コレクションへの追加

XAML には、最初の例で示した正確な構文を使用して、コレクションを初期化するための魔法の簡略構文があります。ただし、プロパティ タイプが を実装している場合にのみ機能しますIList。(はい、それは実際には非ジェネリック IListです。通常は大したことではありませんが、.NET に同梱されているすべてのジェネリック コレクションは と の両方IList<T>を実装していますIList。)

したがって、最初の例を実行できますが、KeyActionsプロパティが を実装する型として宣言されている場合のみですIList。たとえば、プロパティを次のように変更できます。

public ObservableCollection<KeyAction> KeyActions { get {...} }

次に、複数の子要素をプロパティ内に配置するだけで、それらがコレクションに追加されます。

<loc:MyType.KeyActions>
    <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" />
    <loc:KeyAction Action="Hide" Key="Escape" />
</loc:MyType.KeyActions>

XAML は新しいコレクションを作成せず、既存のコレクションに追加するため、これはあなたが求めたものとはまったく異なります。したがって、このオプションを選択した場合、クラスのコンストラクター ( KeyActions = new ObservableCollection<KeyAction>();) でコレクションをインスタンス化する必要があります。これにより、コレクションに要素を追加しようとしたときに null 参照例外が発生しなくなりますAdd

オプション 2: 新しいコレクションの作成

新しいコレクションを作成してプロパティに割り当てる必要がある場合は、それも可能です。List<T>残念ながら、XAML2006 (WPF で現在も使用されているフレーバー) は、ドキュメント全体のルート要素のジェネリックのみをサポートしているため、インスタンス化してプロパティに割り当てることはできません。

でも大丈夫です。WPF と同じ回避策を使用できます。ジェネリック リストから派生する独自の非ジェネリック クラスを作成するだけです。

public class KeyActionCollection : ObservableCollection<KeyAction> {}

次に、XAML でインスタンス化できます。

<loc:CompletionPopupView.KeyActions>
    <loc:KeyActionCollection>
        <loc:KeyAction Action="Show" Key="Space" Modifiers="LeftCtrl" />
        <loc:KeyAction Action="Hide" Key="Escape" />
    </loc:KeyActionCollection>
</loc:CompletionPopupView.KeyActions>

このオプションを選択すると、IEnumerable<KeyAction>希望どおりに財産を宣言したままにすることができます。カスタム リストは、XAML からリストを設定する場合にのみ必要です。

両方のアプローチを組み合わせることもできます。プロパティを読み取り/書き込みおよび typeKeyActionCollectionにし、コンストラクターでインスタンス化すると、XAML は省略形の構文を使用して既存のコレクションに追加するか、新しいコレクションを作成するかを選択できます。実行時コードも同じ選択をする可能性があります。

于 2012-04-30T00:43:35.873 に答える