我正在尝试构建一个ContentControl
派生的控件(我们称它为MyContentControl
),该控件的ControlTemplate
由一个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
并没有做任何事情。编辑(将内容从其他帖子移至原始问题):
这是一个更详细的示例:
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)中提到的断点仅被命中一次。 最佳答案
我之前遇到过同样的问题,可以通过这个(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方式进行命令绑定(bind)是我的方法。尽管您可能不想编写代码后置代码,但请通过适当的事件编写代码后置代码,如下所示。
private void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var content = contentPresenter.Content;
contentPresenter.ClearValue(ContentPresenter.ContentProperty);
contentPresenter.SetValue(ContentPresenter.ContentProperty, content);
}
底线是,您需要重置绑定(bind)的目标对象(在我的情况下,是Content属性)。