从UserControl访问Window的DataContext

时间:2019-04-15 20:45:50

标签: c# wpf xaml user-controls datacontext

在测试应用程序中,我对DataContext感到有些困惑。我用两个不同的UserControls创建了该应用程序。这些UserControl具有自己的DataContext,这些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,并且效果很好。

我的UserControl的代码如下:

<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:Path = DataContext.ActiveView; DataItem = null;目标   元素是'TextBlock'(Name ='');目标属性是“文本”(类型   '字符串')

我不知道为什么。我找到了很多示例,这些示例说明了如何访问祖先的DataContext,但是所有这些示例都像我在TextBlock元素的Text属性中编写的一样……拼命地,我试图更改Path和相对源属性的位置,但是您知道-结果是一样的。我什至尝试将Ancestor的类型更改为local:MainWindow,仅更改为Window(不带x:Type)等。-但您知道-结果是相同的。

您能帮我吗?我在哪里弄错了?我只希望我的UserControl拥有自己的DataContext +从Window的DataContext获取一些值...

1 个答案:

答案 0 :(得分:-1)

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