从UserControl访问Window的DataContext

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从UserControl访问Window的DataContext相关的知识,希望对你有一定的参考价值。

我对我的测试应用程序中的DataContext有点困惑。我用两个不同的UserControl创建了应用程序。这些UserControl有自己的DataContext,它们在自己的ViewModels上设置。我无法访问MainWindow的DataContext,其中显示了用户控件。

这是MainWindow的xaml代码:

<Window x:Class="TestUserControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestUserControl"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="500">

<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>

    <StackPanel>
        <local:MainUserControl VerticalAlignment="Top" HorizontalAlignment="Center"/>
        <ContentControl>
            <ContentControl.Style>
                <Style TargetType="ContentControl">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ActiveView}" Value="Example 1">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <local:UserControl1 />
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding ActiveView}" Value="Example 2">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <local:UserControl2 />
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>

                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </StackPanel> 

您可以注意到,我根据ActiveView变量切换UserControl - 它工作正常。

我的UserControls代码如下所示:

<UserControl x:Class="TestUserControl.UserControl2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:TestUserControl"
             Name="UC2"
             mc:Ignorable="d" 
             d:DesignHeight="250" d:DesignWidth="500">


<UserControl.Resources>
    <local:UserControl2ViewModel x:Key="vm2" />
</UserControl.Resources>
<UserControl.DataContext>
    <Binding Source="{StaticResource vm2}" />
</UserControl.DataContext>

<Grid Width="500" Height="250" Background="Green">
    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">            
        <StackPanel Orientation="Horizontal">
           <Label Content="I am from "/>
            <TextBlock Background="AliceBlue" Text="{Binding Path=DataContext.ActiveView, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"/>
        </StackPanel>
    </StackPanel>
</Grid>

所以,当我运行我的应用程序时,出现错误:

System.Windows.Data错误:4:无法找到绑定源,引用'RelativeSource FindAncestor,AncestorType ='System.Windows.Window',AncestorLevel ='1''。 BindingExpression:路径= DataContext.ActiveView;的DataItem = NULL; target元素是'TextBlock'(Name =''); target属性是'Text'(类型'String')

而且我不知道为什么。我发现了很多例子,如何访问祖先的DataContext,但它们看起来就像我在TextBlock元素中的Text属性中编写的那样......绝望地,我试图改变Path的位置和相对的source属性,但是你知道 - 结果是一样的。我甚至试图将Ancestor的类型更改为local:MainWindow,只是Window(没有x:Type)等等 - 但是你知道 - 结果是一样的。

你能帮帮我吗?我在哪里犯了错误?我只是希望我的UserControls有自己的DataContext +从Window的DataContext中获取一些值...

答案

两种选择让您的生活更轻松。将窗口的VM作为变量(依赖属性)传递给用户控件,或者创建一个静态变量(可能在应用程序之外),它将被设置并将基本窗口的VM返回给任何使用者。获取该信息并将其设置为用户控件上的属性,然后相应地绑定到该属性或依赖项属性。

以上是关于从UserControl访问Window的DataContext的主要内容,如果未能解决你的问题,请参考以下文章

从usercontrol访问表单

如何从其他 UserControl 访问 SimpleChildWindow

如何从UserControl访问父级的DataContext

如何从 xaml 访问 UserControl 内的按钮?

我可以从 UserControl 绑定到 DataTemplate 吗?

如何从代码隐藏中访问UserControl中样式的Setter中ControlTemplate中定义的Control实例?