如何获取Child控件WPF的Datacontext

时间:2016-01-11 06:27:50

标签: c# wpf datacontext

在App.xaml中

<DataTemplate DataType="{x:Type vm:CurrentSheetVM}">
                    <vw:CurrentSheetV/>
                </DataTemplate>

    <DataTemplate DataType="{x:Type vm:ParentVM}">
                    <vw:ParentControlV/>
                </DataTemplate>

在XAML中:

 <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" > 
                <ContentControl Name="childCtrl1" Content="{Binding CurrentSheet1}"/>
                <ContentControl Name="childCtrl2" Content="{Binding CurrentSheet2}"/>
    </StackPanel>

在ParentVM中:

private ViewModelBase currentSheet1;
       public ViewModelBase CurrentSheet1
       {
           get { return currentSheet1; }
           set { currentSheet = value;
           this.OnPropertyChanged("CurrentSheet1");
           }
       }

public ParentVM()
{
CurrentSheet1= new CurrentSheetVM(some param1);
CurrentSheet2= new CurrentSheetVM(some param2);
}

中的代码

Object dc_Child1= childCtrl1.DataContext;
Object dc_Child2= childCtrl2.DataContext;

这里试图获取两个子控件的datacontext,但是它在dc_Child1和dc_Child2中显示父元素DataContext。 有没有办法获得这两个数据文件?

1 个答案:

答案 0 :(得分:3)

问题是设置ContentControl.Content与设置ContentControl.DataContext不一样。

考虑这段代码。以下是视图模型:

public class ParentViewModel
{
    public ChildViewModel_A Child_A { get; } = new ChildViewModel_A
    {
        IntProperty = 100
    };

    public ChildViewModel_B Child_B { get; } = new ChildViewModel_B
    {
        StringProperty = "Hello, world!"
    };
}

public class ChildViewModel_A
{
    public int IntProperty { get; set; }
}

public class ChildViewModel_B
{
    public string StringProperty { get; set; }
}

这是标记:

<Window x:Class="DataContextsDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataContextsDemo">

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

    <StackPanel>
        <StackPanel.Resources>
            <DataTemplate DataType="{x:Type local:ChildViewModel_A}">
                <TextBlock Text="{Binding IntProperty}"/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:ChildViewModel_B}">
                <TextBlock Text="{Binding StringProperty}"/>
            </DataTemplate>
        </StackPanel.Resources>

        <ContentControl x:Name="Child_A_View" Content="{Binding Child_A}"/>
        <ContentControl x:Name="Child_B_View" Content="{Binding Child_B}"/>
        <Button Content="Click me!" Click="Button_Click"/>
    </StackPanel>
</Window>

默认情况下,ContentControl s都从其父级继承“DataContext”(在此特定情况下,来自祖父,Window)。

如果您点击该按钮,则代码背后的代码为:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Debug.WriteLine(Child_A_View.DataContext == Child_B_View.DataContext);
}

会将True写入输出窗口,因为两个控件的数据上下文都是ParentViewModel的实例。

但是如果XAML会像这样修改一下:

    <ContentControl x:Name="Child_A_View" DataContext="{Binding Child_A}" Content="{Binding}"/>
    <ContentControl x:Name="Child_B_View" DataContext="{Binding Child_B}" Content="{Binding}"/>

Debug.WriteLine会写False,因为这会明确设置DataContext并违反默认的“继承”策略。注意,这个表达式:

DataContext="{Binding Child_A}"

仍适用于父DataContext,而这一个:

Content="{Binding}"

适用于新数据上下文,由上一个表达式指定。

另请注意,此示例中的内容控件的内容将保持不变。唯一的变化是数据上下文。