Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 从DataTrigger内绑定子DataContext_Wpf_Mvvm - Fatal编程技术网

Wpf 从DataTrigger内绑定子DataContext

Wpf 从DataTrigger内绑定子DataContext,wpf,mvvm,Wpf,Mvvm,我一直在尝试开发一个单选按钮栏(样式为ToggleButtons),用于选择ContentControl中显示的内容。我已经能够使用DataTrigger在ContentControl中显示正确的视图,根据该视图选中RadioButton,但我也尝试将视图模型从父DataContext绑定到子DataContext,但没有成功。最小样本如下所示: <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schem

我一直在尝试开发一个单选按钮栏(样式为ToggleButtons),用于选择ContentControl中显示的内容。我已经能够使用DataTrigger在ContentControl中显示正确的视图,根据该视图选中RadioButton,但我也尝试将视图模型从父DataContext绑定到子DataContext,但没有成功。最小样本如下所示:

<Window x:Class="WpfApplication1.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:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
            <RadioButton Name="rbShowChild" Content="Show Child" Style="{StaticResource {x:Type ToggleButton}}" />
        </StackPanel>

        <ContentControl Grid.Row="1">
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsChecked, ElementName=rbShowChild}" Value="True">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <local:ChildView DataContext="{Binding ChildViewModel, PresentationTraceSources.TraceLevel=High}"/>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </Grid>
</Window>
        var window = new MainWindow()
        {
            DataContext = new MainWindowViewModel()
        };
        window.Show();
主窗口DataContext设置如下:

<Window x:Class="WpfApplication1.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:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
            <RadioButton Name="rbShowChild" Content="Show Child" Style="{StaticResource {x:Type ToggleButton}}" />
        </StackPanel>

        <ContentControl Grid.Row="1">
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsChecked, ElementName=rbShowChild}" Value="True">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <local:ChildView DataContext="{Binding ChildViewModel, PresentationTraceSources.TraceLevel=High}"/>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </Grid>
</Window>
        var window = new MainWindow()
        {
            DataContext = new MainWindowViewModel()
        };
        window.Show();
输出窗口(带有PresentationTraceSources.TraceLevel=High)显示以下内容:

System.Windows.Data Error: 3 : Cannot find element that provides DataContext. BindingExpression:Path=ChildViewModel; DataItem=null; target element is 'ChildView' (Name=''); target property is 'DataContext' (type 'Object')
这让我想到MainWindow.DataContext并不是用来解析触发器中的“{Binding ChildViewModel}”表达式的DataContext,但是我在触发器上找不到任何DataContext属性,在搜索中也找不到任何东西来建议对此的答案


我非常感谢您提出任何解决此问题的建议。

更新:问题似乎在于您如何设置数据上下文

在XAML中设置窗口的DataContext,然后将
ContentControl
的数据上下文设置为
ChildViewModel
。然后设置实际显示的
内容
(又称儿童视图)
ContentControl
是此视图的宿主,因此它应该是
DataContext
供应商。我自己有点不确定正在进行的确切机制,但我知道下面的代码实际上是有效的

注意,您的XML名称空间可能与下面的代码不同。相应地调整

<Window.DataContext>
    <!-- Data Context added here OR in code-behind initialize-->
    <local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
        <RadioButton Name="rbShowChild" Content="Show Child" Style="{StaticResource {x:Type ToggleButton}}" />
    </StackPanel>

    <!-- Bind the ContentControls Data context-->
    <ContentControl DataContext="{Binding ChildViewModel}" Grid.Row="1">
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsChecked, ElementName=rbShowChild}" Value="True">
                        <Setter Property="Content">
                            <Setter.Value>
                                <!-- Just simply set the view content here, no binding.-->
                                <local:ChildView />
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>
</Grid>


这样做,我已经在一个项目中很好地运行了您的应用程序。

谢谢您的回复,Toskr。我尝试了这两种方法,但我认为这并不能解决我的问题。MainWindowDataContext似乎工作正常,即使在原始项目中也是如此。未设置的是ChildView数据上下文。当您在这些更改后说它对您有效时,您是在单击按钮时看到绑定的文本字符串“it works!”还是仅看到字符串“Child”(未绑定,只是在XAML中)?触发器正在显示子视图,只是没有设置子DataContext。我看到显示字符串“It works”。也许可以发布有关如何以及在何处设置数据上下文的信息。创建主窗口并设置其数据上下文的原始代码位于App.OnStartup()中。我还将您建议的更改添加到MainWindow构造函数和XAML中。我不知道为什么它对你有效,但对我无效。此外,如果我将它添加到我的主窗口中,它会在那里显示“它有效!”,这同样意味着我的主窗口DataContext设置正确。从App.OnStartup设置主窗口DataContext时,如果不在您建议的任何位置重新设置,它对您是否有效?我要到早上才会在电脑前,所以我会深入研究。然而,这感觉可能是其中一种情况,在这种情况下,您可能忽略了一些导致事情无法按预期工作的小错误。我建议你仔细检查一下。例如,您是否在子视图代码隐藏中执行了任何操作?在运行时有任何可能破坏孩子绑定的内容吗?也许是你忘了移除的东西?