【问题标题】:Programmatically set a Binding to a DataTemplate以编程方式设置绑定到 DataTemplate
【发布时间】:2017-09-21 13:17:57
【问题描述】:

我正在编写一个模型来重构和现有应用程序,我在后面的代码中设置 WPF 绑定时遇到了一些问题......上下文是我有一个 RadPane(来自 Telerik 套件,RadDocking 控件),我想设置标题模板。现在我正在使用这种方法,但是当我停靠一个窗格时,我得到的标题是 System.而不是我得到的内容“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>

【问题讨论】:

  • 我不确定您的标头模板在做什么,或者view 的DataContext 与它有什么关系,但我认为您只想设置标头模板:pane.HeaderTemplate = dataTemplate;。然后,也许,pane.Header = ((IView)view).DataContext;——但如果我知道你想在标题中放入什么,以及数据模板试图用它做什么,我可以更确定。
  • 那行得通,顺便说一句,我为什么还要设置Headerproperty?
  • HeaderTemplate 告诉控件您希望如何显示Header 的值。你可以在没有HeaderTemplate 的情况下尝试一下,看看你会得到什么。但Header 可以是任何东西——控件、字符串、整数(在这种情况下可能不需要模板)或视图模型,在这种情况下您可能需要一个模板。
  • 但我将DataContext设置为((IView)view).DataContext;并且dataTemplate 是在与DataContext 不同的类中定义的
  • 数据模板的定义位置无关紧要。里面有什么很重要。我完全听不懂你在说什么。

标签: c# wpf telerik


【解决方案1】:

标题模板告诉控件您希望如何显示您为Header 提供的对象。如果Header 只是一个字符串,而您只想将其显示为普通的 UI 文本,则无需费心使用模板。同样,如果 Header 是一个控件。但是,如果您费心编写标题DataTemplate,我想您有这样做的理由。

所以只要给它模板:

pane.HeaderTemplate = dataTemplate;

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

但我的猜测是您想将其用作标题模板的DataContext,而这正是它应该使用的。如果是这种情况,您希望像这样设置实际的标题内容:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2011-02-01
    • 2015-06-04
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 2012-05-09
    • 2011-09-07
    • 2015-10-29
    • 2011-05-08
    相关资源
    最近更新 更多