【问题标题】:WPF: Unable to access static resource from child controlWPF:无法从子控件访问静态资源
【发布时间】:2013-03-25 04:19:45
【问题描述】:

我不知道如何从子控件的资源部分中访问我的 Window.Resources。我在子控件中定义了一个 DataTemplate,并希望该 DataTemplate 绑定到我的视图模型上的 ICommand(在 Window.Resources 中定义)

编辑: 我将RadPaneGroup 代码添加到主窗口 XAML。这是我实例化ProjectsViewModel 对象的地方。 RadDocumentPane 中包含的 ProjectsView 控件是我在下面列出的子控件。

主窗口

<Window.Resources>
    <viewModels:ProjectsViewModel x:Key="ProjectsViewModel" />
</Window.Resources>
<telerik:RadDocking HasDocumentHost="False" >
    <telerik:RadSplitContainer>
        <telerik:RadPaneGroup DataContext="{StaticResource ProjectsViewModel}">
            <telerik:RadDocumentPane Header="Projects">
                <views:ProjectsView/>
            </telerik:RadDocumentPane>
        </telerik:RadPaneGroup>
    </telerik:RadSplitContainer>
    ...

儿童控制

<Control.Resources>
    <!--Data template for the Task object-->
    <DataTemplate  DataType="{x:Type models:Task}">
        <StackPanel>
            <TextBlock Text="{Binding DisplayName}" Foreground="Red" 
                       FontSize="16" FontFamily="Verdana" />
            <telerik:RadContextMenu.ContextMenu>
                <telerik:RadContextMenu >
                    <telerik:RadMenuItem Header="New Project" 
                            Command="{Binding NewProjectCommand}"/>
                </telerik:RadContextMenu>
            </telerik:RadContextMenu.ContextMenu>
        </StackPanel>
    </DataTemplate>

上述 XAML 上的绑定正在尝试绑定到 Task 对象。但是,我的 ICommand 位于 ViewModel (ProjectsViewModel) 中。我尝试将绑定更改为Command="{Binding NewProjectCommand, Source={StaticResource ProjectsViewModel}},但这会引发异常。

我做错了什么?

谢谢,

【问题讨论】:

  • 您的 ChildControlUserControl 还是 CustomControl
  • 我的控件是 s UserControl - 基本上为我的主窗口中的一个窗格保存一个 TreeView。
  • 进行了编辑以显示如何在 XAML 中实例化 ProjectsViewModel。
  • 抛出什么样的异常?

标签: wpf binding staticresource


【解决方案1】:

您的 DataTemplate 看起来像是在 ItemsControl(例如 ListBox)中使用,所以正如您所说,Command="{Binding NewProjectCommand}" 将尝试绑定到 Task 类型的属性,而您确实想绑定到父容器的属性。因此,您需要使用 RelativeSource 绑定,例如:

Command="{Binding Path=DataContext.NewProjectCommand, RelativeSource=
         {RelativeSource FindAncestor, AncestorType={x:Type views:ProjectsView}}}" 

【讨论】:

    【解决方案2】:

    您可以使用与Why can't I use DataContext={Binding} for my context menu? 的问题类似的方法来解决此问题。

    这可能不起作用的基本原因是 ContextMenu 在技术上是一个单独的窗口,因此它有自己的可视化树,可能不包含在文档窗格的逻辑树中。结果,它不知道如何从包含视图中找到资源。

     DataContext="{Binding PlacementTarget.DataContext.NewProjectCommand,
                   RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type telerik:RadContextMenu}}}"
    

    【讨论】: