WPF:设置用户控件数据上下文

Posted

技术标签:

【中文标题】WPF:设置用户控件数据上下文【英文标题】:WPF: Set UserControl DataContext 【发布时间】:2012-12-16 12:52:22 【问题描述】:

我有以下MainWindow,它布置了左侧导航面板和右侧显示区域(两者都是UserControls)。

谁能解释如何将导航面板的DataContext (LinksView.xaml) 分配给LinksViewModel.csLinksViewModel.cs。我想将命令(BtnCompanyClickCommand)绑定到按钮并在LinksViewModel.cs 中定义BtnCompanyClickCommand

我尝试了在 *** 上找到的各种方法来设置 DataContext,但这些解决方案似乎都不起作用(绑定 RelativeSource、命名视图和绑定到名称等)。

MainWindow.xaml

<StackPanel Orientation="Horizontal">
    <vw:LinksView DataContext="Binding RelativeSource=RelativeSource Self"/>
    <ContentControl Content="Binding CurrentUserControl" />

</StackPanel>

LinksView.xaml

<StackPanel Orientation="Vertical">
    <Button Content="Company" Width="75" Margin="3" Command="Binding ElementName=Links,Path=BtnCompanyClickCommand" />
</StackPanel>

FormsDictionary.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:vm="clr-namespace:SidekickAdmin.ViewModel"
                    xmlns:vw="clr-namespace:SidekickAdmin.View">

    <DataTemplate DataType="x:Type vm:CompanySummaryViewModel">
        <vw:CompanySummaryView>
            <ContentControl Content="Binding " />
        </vw:CompanySummaryView>
    </DataTemplate>

    <DataTemplate DataType="x:Type vm:LinksViewModel">
        <vw:LinksView />
    </DataTemplate>

</ResourceDictionary>

编辑

所以我终于遇到了这个explanation 如何设置 UserControl 的 DataContext,这必须在 UserControl 的第一个子项上完成。

这是修改后的 LinksView.xaml 有效。

<StackPanel Orientation="Vertical">
    <StackPanel.DataContext>
        <vm:LinksViewModel />   <!-- Bind the items in StackPanel to LinksViewModel -->
    </StackPanel.DataContext>

    <Button Content="Company" Width="75" Margin="3" Command="Binding BtnCompanyClickCommand" />
</StackPanel>

但是,我仍然不清楚为什么我必须设置子元素的 DataContext 而不是 UserControl,以及为什么 LinksView 的 DataTemplate(在 FormsDictionary.xaml 中设置)不绑定到 LinksViewModel 的 DataContext。任何解释将不胜感激。

【问题讨论】:

如果您删除您在编辑中添加的 DataContext 片段,它是否仍然有效?我假设您将在这种情况下设置 MainWindow 视图的数据上下文。 如果我从我的编辑中删除 ... 则 LinksView 的 DataContext 为 MainWindowViewModel。 【参考方案1】:

首先,您必须在 XAML 代码中引用您的 DataContext (LinksViewModel.cs)。 您可以通过直接实例化它或使用 ResourceDictionary 来做到这一点。在后一种情况下,您可以在某个 .cs 文件或 ResourceDictionary .xaml 文件中实例化您的 DataConext 并将其存储在一个命名的 ResourceDictionary 中,您可以稍后在其中找到参考。

其次,您只需将 View 元素(如 LinksView.xaml)的 DataContext 属性与相应的 DataContext 相关联。

这是相当高级的,没有任何代码,但这是它背后的基本思想。

【讨论】:

谢谢,我知道我必须将 DataContext 连接到 XAML,就像我说的那样,我已经尝试过针对 SO 上的其他问题提出的各种解决方案。但是,我无法让这些与我的应用程序一起使用,所以我希望有人能够真正建议一些我可以尝试的代码。我确实尝试在 ResourceDictionary 中设置 LinksView 的 DataContext 但这没有用。【参考方案2】:

MainWindowViewModel 中应该有 LinksViewModel 的实例:

MainWindowViewModel.cs:

class MainWindowViewModel

    public MainWindowViewModel()
    
         LinksVM = new LinksViewModel();
    

    public LinksViewModel LinksVM  get; private set; 

MainWindow.xaml

<StackPanel Orientation="Horizontal">
    <vw:LinksView DataContext="Binding LinksVM"/>
    <ContentControl Content="Binding CurrentUserControl" />
</StackPanel>

LinksView.xaml

<StackPanel Orientation="Vertical">
    <Button Content="Company" Width="75" Margin="3" Command="Binding BtnCompanyClickCommand" />
</StackPanel>

由于 LinksView 是在 MainWindow 中显式创建的,因此在 DataTemplate 中不需要 - 可以将其删除

<DataTemplate DataType="x:Type vm:LinksViewModel">
    <vw:LinksView />
</DataTemplate>

【讨论】:

以上是关于WPF:设置用户控件数据上下文的主要内容,如果未能解决你的问题,请参考以下文章

如何分别渲染用户控件

wpf如何根据输入信息动态生成treeview

WPF - 设置相对于用户控件的对话框窗口位置

WPF 样式不适用于已设置样式的用户控件

如何修复 WPF 控件的简单 MouseOver 动画?

用户控件中的 WPF 将控件模板的内容设置为依赖属性的值