我正在尝试构建一个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";

我希望当我在那些控件上设置内容时,MyTemplateSelectorDataTemplateSelector.SelectTemplate()都会调用contentControlmyContentControl方法的替代。

实际上,仅针对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
      }
    }
    
  • ContentControlMyContent控件添加到主窗口中(例如):
    <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属性)。

    09-11 20:24