我正在创建一个自定义控件,并且正在尝试为列表框项创建部分指定的模板。模板有一些预定义的部分,并且应该有另一个部分可以在使用控件时进行模板化。
为此,我创建了一个名为 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”没有在样式中的任何地方定义。
我尝试的第三个选项是在 OnApplyTemplate 覆盖中应用 ContentTemplate 但这也不起作用:
var cp = itemsControlElement.ItemTemplate.LoadContent() as ContentPresenter;
cp.ContentTemplate = SuggestionItemTemplate;
在所有情况下,我的网格都有两列,切换按钮可见,但内容演示者简单地打印出视图模型的类型名称。(如果 ContentTemplate 为空,我相信这是默认行为)。
这甚至可能吗?有没有其他方法可以指定部分模板,然后只在必要时添加自定义模板部分?
作为目前的解决方法,我可以指定
ItemTemplate="{TemplateBinding SuggestionItemTemplate}"
对于列表框,然后在我使用此控件的任何地方复制/粘贴通用模板。但这是我希望首先避免的行为。
谢谢!
编辑:我对所有代码块都使用了代码标签,但由于某种原因它们没有突出显示。:/