以编程方式将绑定设置为 DataTemplate

Programmatically set a Binding to a DataTemplate

我正在编写一个模型来重构和现有应用程序,我在代码隐藏中设置 WPF 绑定时遇到了一些问题...上下文是我有一个 RadPane(来自 Telerik 套件,RadDocking 控件)并且我想要设置 header 模板。现在我正在使用这种方法,但是当我 dock-out 一个窗格时,我得到了 header 作为系统。而不是我得到的内容“System.Windows.Controls.StackPanel”

这是我现有的代码

var pane = new RadDocumentPane();
var view = CreateViewContent(viewModel);

 pane.DataContext = ((IView)view).DataContext;
       
 pane.Content = view;

 var dataTemplate = (DataTemplate)Application.Current.Resources["Default"];

 var x = (StackPanel) dataTemplate.LoadContent();

 x.DataContext = ((IView)view).DataContext;

 pane.Header=x;
 pane.Title=x;

我想像

 Binding binding = new Binding("?????");

 BindingOperations.SetBinding(pane, HeaderedContentControl.HeaderTemplateProperty, binding);

但我不知道如何告诉绑定我想引用 dataTemplate

更新 1

我必须创建 DataTemplate 的原因是我必须添加一些此处定义的上下文菜单功能

<DataTemplate x:Key="Default">
    <StackPanel Orientation="Horizontal"  >
        <TextBlock Text="{Binding Title,Mode=OneWay, UpdateSourceTrigger=Default}" Margin="3,0,0,0" >
        <telerik:RadContextMenu.ContextMenu>
            <telerik:RadContextMenu x:Name="ContextMenu">
                <telerik:RadMenuItem Header="Chiudi questo">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Click">
                        <catel:EventToCommand Command="{Binding CloseCommand, Source={StaticResource PaneCommands}}" CommandParameter="{Binding}" DisableAssociatedObjectOnCannotExecute="False" />
                    </i:EventTrigger>
                        </i:Interaction.Triggers>
                </telerik:RadMenuItem>
                <telerik:RadMenuItem Header="Chiudi tutti">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Click">
                            <catel:EventToCommand Command="{Binding CloseAllCommand, Source={StaticResource PaneCommands}}" CommandParameter="{Binding}" DisableAssociatedObjectOnCannotExecute="False" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </telerik:RadMenuItem>
                <telerik:RadMenuItem Header="Chiudi tutti tranne questo">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Click">
                            <catel:EventToCommand Command="{Binding CloseAllExceptThisCommand, Source={StaticResource PaneCommands}}" CommandParameter="{Binding}" DisableAssociatedObjectOnCannotExecute="False" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </telerik:RadMenuItem>
            </telerik:RadContextMenu>
        </telerik:RadContextMenu.ContextMenu>
            
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDown">
                <catel:EventToCommand Command="{Binding MouseDownCommand, Source={StaticResource PaneCommands}}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
        </TextBlock>


    </StackPanel>
</DataTemplate>

header 模板告诉控件您希望如何显示您为 Header 提供的 object。如果 Header 只是一个字符串,而您只想将其显示为普通的 UI 文本,则无需费心使用模板。同样,如果 Header 是一个控件。但是,如果您不厌其烦地写了一个 header DataTemplate,我想您这样做是有原因的。

所以只要给它模板:

pane.HeaderTemplate = dataTemplate;

现在,我不知道您的模板在做什么,也不知道您为什么要写一个模板,或者视图的 DataContext 中有什么(应该是视图模型,但实际上它可以是任何东西)。

但我猜它是您想用作 header 模板的 DataContext 的东西,而这正是它应该的样子。如果是这种情况,您需要像这样设置实际的 header 内容:

pane.Header = ((IView)view).DataContext;

...也就是说,除非 ((IView)view).DataContext 可能会在运行时更改。这是可能发生的,这就是绑定的目的。然后你会这样做。

pane.SetBinding(
    HeaderedContentControl.HeaderProperty,
    new Binding("DataContext") { Source = view });

查看the documentation for RadDocumentPane,它有TopTemplateTitleTemplate属性,他们没有提到HeaderTemplate。那里发生了很多事情。但它似乎是这样工作的。