6

我正在尝试构建一个ContentControl-derived 控件(我们称之为它MyContentControl),它将ControlTemplate由一个DataTemplateSelector-derived 类型的实例设置它(我们称之为它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()contentControlmyContentControl

实际上,它只为 contentControl 调用。我需要做什么(为什么!)才能使它也起作用myContentControl

(不确定它是否相关,但目前MyContentControl除了DependencyProperties覆盖DefaultStyleKeyProperty.

编辑(将其他帖子中的内容移至原始问题):

这是一个更详细的示例:

  1. 创建 MyContentControl:

    public class MyContentControl : ContentControl
    {
      static MyContentControl()
      {
        DefaultStyleKeyProperty.OverrideMetadata(typeof (MyContentControl),
                                             new FrameworkPropertyMetadata(typeof (MyContentControl)));
      }
      public MyContentControl() {}
    }
    
  2. 创建MyTemplateSelector

    public class MyTemplateSelector : DataTemplateSelector
    {
      public override DataTemplate SelectTemplate(object item, DependencyObject container)
      {
        return null;  // <== Place the breakpoint here
      }
    }
    
  3. 添加ContentControlMyContent控制到您的主窗口(例如):

    <StackPanel>
        <local:MyContentControl x:Name="myContentControl" />
        <ContentControl x:Name="contentControl" />
    </StackPanel>
    
  4. InitializeComponent在之后(或在处理程序中)的某处添加此代码Loaded

    myContentControl.ContentTemplateSelector = new MyTemplateSelector();
    myContentControl.Content = "123";
    
    contentControl.ContentTemplateSelector = new MyTemplateSelector();
    contentControl.Content = "ABC";
    

步骤(2)中提到的断点只被命中一次,fo​​r content="ABC"and contentControlelement。

4

3 回答 3

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>

希望这可以帮助。

于 2011-09-30T14:32:05.617 回答
2

我之前遇到过同样的问题,我用这个(通知 DataTemplateSelector 关于更改)提示解决了它。

我的问题是,我想要一个 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);
    }

底线是,您需要重置绑定的目标对象(在我的例子中是 Content 属性)。

于 2010-08-16T07:20:50.610 回答
0

您可能需要发布更多代码,因为我刚刚创建了一个简单的示例,它运行良好。我DataTemplate只包含 a TextBox,我DataTemplateSelector总是返回那个DataTemplate,并且 aContentControl和一个派生自ContentControl使用 my的类DataTemplateSelector。在这两种情况下TextBox都显示了 a。

于 2009-07-17T11:08:56.117 回答