WPF:设置UserControl数据上下文

WPF:设置UserControl数据上下文,wpf,button,data-binding,mvvm,datacontext,Wpf,Button,Data Binding,Mvvm,Datacontext,我有下面的main窗口,它布置了左侧导航面板和右侧显示区域(这两个都是UserControls) 有人能解释一下如何将导航面板(LinksView.xaml)的DataContext分配给LinksViewModel.cs。我想将命令(BtnCompanyClickCommand)绑定到按钮,并在LinksViewModel.cs中定义BtnCompanyClickCommand 我尝试了在StackOVerflow上找到的各种方法来设置DataContext,但这些解决方案似乎都不起作用(绑定

我有下面的
main窗口
,它布置了左侧导航面板和右侧显示区域(这两个都是
UserControls

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

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

main window.xaml

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

</StackPanel>
<StackPanel Orientation="Vertical">
    <Button Content="Company" Width="75" Margin="3" Command="{Binding ElementName=Links,Path=BtnCompanyClickCommand}" />
</StackPanel>
<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>

LinksView.xaml

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

</StackPanel>
<StackPanel Orientation="Vertical">
    <Button Content="Company" Width="75" Margin="3" Command="{Binding ElementName=Links,Path=BtnCompanyClickCommand}" />
</StackPanel>
<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>

FormsDictionary.xaml

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

</StackPanel>
<StackPanel Orientation="Vertical">
    <Button Content="Company" Width="75" Margin="3" Command="{Binding ElementName=Links,Path=BtnCompanyClickCommand}" />
</StackPanel>
<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>

编辑

因此,我最终遇到了如何设置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中设置)没有绑定到LinksView的DataContext。任何解释都将不胜感激。

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

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


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

在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>


谢谢,我知道我必须将DataContext连接到XAML,正如我所说,我已经尝试了针对其他问题提出的各种解决方案。但是,我无法让这些代码与我的应用程序一起工作,所以我希望有人能够实际建议一些我可以尝试的代码。我确实尝试在ResourceDictionary中设置LinksView的DataContext,但没有成功。如果删除在编辑中添加的DataContext片段,它是否仍然有效?我假设在此场景中您将设置MainWindow视图的datacontext。。。从我的编辑,然后LinksView有一个MainWindowViewModel的DataContext。如果LinksView上没有DataContext显式设置,WPF将在树上查找一个—在您的例子中,是MainWindow上的DataContext。