カスタム コントロールを作成していて、リスト ボックス項目用に部分的に指定されたテンプレートを作成しようとしています。テンプレートにはいくつかの事前定義された部分があり、コントロールを使用するときにテンプレート化できる別の部分があるはずです。
このために、次のように SuggestionItemTemplate という名前の依存関係プロパティを作成しました。
public static readonly DependencyProperty SuggestionItemTemplateProperty =
DependencyProperty.Register("SuggestionItemTemplate",
typeof(DataTemplate),
typeof(AutoSuggestTextBox),
new PropertyMetadata(null));
私のカスタム コントロールの generic.xaml には、次のものがあります。
<Style TargetType="local:AutoSuggestTextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:AutoSuggestTextBox">
<Grid>
<ListBox x:Name="ItemsControl">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0"
ContentTemplate="{TemplateBinding SuggestionItemTemplate}"
Content="{Binding}" />
<ToggleButton Grid.Column="1"
x:Name="DetailsHover"
ClickMode="Hover"
Style="{StaticResource DetailsToggleButtonStyle}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
残念ながら、DataTemplate にネストされた ContentPresenter 内から TemplateBinding を使用できないため、これは機能しません。(メンバー「SuggestionItemTemplate」が認識されないか、アクセスできません。)
また、祖先バインディング (Silverlight 5 で利用可能) を次のように使用しようとしました。
<ContentPresenter Grid.Column="0"
ContentTemplate="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=local:AutoSuggestTextBox}, Path=SuggestionItemTemplate}"
Content="{Binding}" />
しかし、これはバインディングエラーになります:
Error: System.Exception: BindingExpression_CannotFindAncestor
これは、カスタム コントロールの ControlTemplate 内にいて、「local:AutoSuggestTextBox」がスタイルのどこにも定義されていないために発生すると思います。
私が試した 3 番目のオプションは、OnApplyTemplate オーバーライドで ContentTemplate を適用することでしたが、これも機能しません。
var cp = itemsControlElement.ItemTemplate.LoadContent() as ContentPresenter;
cp.ContentTemplate = SuggestionItemTemplate;
すべての場合で、2 つの列を持つグリッドを取得します。トグル ボタンは表示されますが、コンテンツ プレゼンターは単純にビュー モデルの型名を出力します。(ContentTemplate が null の場合、これがデフォルトの動作だと思います)。
これは可能ですか?部分的なテンプレートを指定し、必要に応じてカスタマイズされたテンプレート パーツのみを追加する他の方法はありますか?
今のところ回避策として、指定できます
ItemTemplate="{TemplateBinding SuggestionItemTemplate}"
リスト ボックスの場合は、このコントロールを使用するすべての場所に汎用テンプレートをコピーして貼り付けます。しかし、これは私が最初に避けたいと思っている行動です。
ありがとう!
編集:コードのすべてのブロックにコードタグを使用しましたが、何らかの理由で強調表示されていません。:/