我正在尝试构建一个ContentControl
派生的控件(我们称之为MyContentControl
),它将ControlTemplate
的{{1}}设置为派生DataTemplateSelector
输入(我们称之为MyTemplateSelector
)。
当我尝试这个时:
ContentControl contentControl = new ContentControl();
contentControl.ContentTemplateSelector = new MyTemplateSelector();
contentControl.Content = "Some ContentControl Content";
MyContentControl myContentControl = new MyContentControl();
myContentControl.ContentTemplateSelector = new MyTemplateSelector();
myContentControl.Content = "Some MyControl Content";
我希望,当我在这些控件上设置内容时,会MyTemplateSelector
和DataTemplateSelector.SelectTemplate()
调用contentControl
覆盖myContentControl
方法。
实际上,只为contentControl调用它。我需要做什么(以及为什么!)使其适用于myContentControl
?
(不确定它是否相关,但目前MyContentControl
除了覆盖DependencyProperties
的元数据信息外,对DefaultStyleKeyProperty
不执行任何操作。
编辑(将内容从其他帖子转移到原始问题):
这是一个更详细的例子:
创建MyContentControl:
public class MyContentControl : ContentControl
{
static MyContentControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof (MyContentControl),
new FrameworkPropertyMetadata(typeof (MyContentControl)));
}
public MyContentControl() {}
}
创建MyTemplateSelector
:
public class MyTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return null; // <== Place the breakpoint here
}
}
将ContentControl
和MyContent
控件添加到主窗口(例如):
<StackPanel>
<local:MyContentControl x:Name="myContentControl" />
<ContentControl x:Name="contentControl" />
</StackPanel>
在InitializeComponent
(或Loaded
处理程序)之后的某处添加此代码:
myContentControl.ContentTemplateSelector = new MyTemplateSelector();
myContentControl.Content = "123";
contentControl.ContentTemplateSelector = new MyTemplateSelector();
contentControl.Content = "ABC";
对于content="ABC"
和contentControl
元素,步骤(2)中提到的断点只被命中一次。
答案 0 :(得分:2)
之前我遇到了同样的问题,我用这个(Notify DataTemplateSelector about the change)提示解决了这个问题。
我的问题是,我想要一个ContentPresenter,当ComboBox选择发生变化时,它会更改嵌入式UserControl。
Combobox + ContentPresenter XAML
<ComboBox Name="comboBoxControl" Grid.Row="1" Grid.Column="1" SelectionChanged="comboBox_SelectionChanged">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding Path=ChangeControlCommand, Mode=OneWay}" CommandParameter="{Binding Path=SelectedItem.Content, ElementName=comboBoxControlType}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ComboBoxItem>UserControl-1-</ComboBoxItem>
<ComboBoxItem>UserControl-2-</ComboBoxItem>
</ComboBox>
<ContentPresenter Name="contentPresenter" ContentTemplateSelector="{Binding Source={StaticResource controlCueTemplateSelector}}"
Content="{Binding}" />
正如您所看到的,使用MVVM方式绑定命令是我的方法。虽然您可能不想编写代码隐藏,但请使用适当的事件编写代码隐藏,如下所示。
private void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var content = contentPresenter.Content;
contentPresenter.ClearValue(ContentPresenter.ContentProperty);
contentPresenter.SetValue(ContentPresenter.ContentProperty, content);
}
Bottomline是,你需要重置绑定的目标对象(在我的例子中,是Content属性)。
答案 1 :(得分:2)
我遇到了同样的问题,DataTemplateSelector已经应用于ContentControl而不是我的派生控件的原因隐藏在我的派生控件的ControlTemplate中。我只是忘了为ContentTemplateSelector添加模板绑定:
<ControlTemplate TargetType="{x:Type local:UniControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"/>
</Border>
希望这有帮助。
答案 2 :(得分:0)
您可能需要发布更多代码,因为我刚创建了一个简单的示例,它运行正常。我的DataTemplate
只包含TextBox
,我的DataTemplateSelector
始终返回DataTemplate
,而ContentControl
和来自ContentControl
的类都使用我的DataTemplateSelector
TextBox
。在这两种情况下都显示了{{1}}。