WPF MVVM - 视图不从其父窗口继承数据上下文

发布于 2025-01-17 21:54:56 字数 6880 浏览 3 评论 0原文

在搜索很多解决方案后,我问这个问题,但它们都无法使用,

我的问题可以通过这种方式恢复:我有一个主窗口(mainwindow.xaml),我有一个视图(parametersview.xaml)。

我还拥有MainViewModel.cs文件,这是我的DataContext共有的。

首先,我想使参数视图从mainviewModel的MainWindows View继承DataContext。

mainwindow.xaml

<Window x:Class="MVVMTest.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:MVVMTest"
        mc:Ignorable="d"
        WindowStyle="None"
        AllowsTransparency="True"
        Background="Transparent"
        Title="MainWindow" Height="450" Width="800">

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

    <Border Background="#272537"
            CornerRadius="35">

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>
                <RowDefinition Height="70"/>
                <RowDefinition/>
            </Grid.RowDefinitions>

            <StackPanel Grid.Row="1">

                <RadioButton Content="Acquisition"
                             Height="50"
                             Foreground="White"
                             FontFamily="Century Gothic"
                             FontSize="20"
                             Style="{StaticResource MenuButtonTheme}"
                             />

                <RadioButton Content="Data visualization"
                             Height="50"
                             Foreground="White"
                             FontFamily="Century Gothic"
                             FontSize="20"
                             Style="{StaticResource MenuButtonTheme}"
                             Command="{Binding DataVisuViewCommand}"/>

                <RadioButton Content="Parameter"
                             Height="50"
                             Foreground="White"
                             FontFamily="Century Gothic"
                             FontSize="20"
                             Style="{StaticResource MenuButtonTheme}"
                             IsChecked="True"
                             Command="{Binding ParameterViewCommand}"/>

                <RadioButton Content="Post processing"
                             Height="50"
                             Foreground="White"
                             FontFamily="Century Gothic"
                             FontSize="20"
                             Style="{StaticResource MenuButtonTheme}"
                             Command="{Binding MembersViewCommand}"/>

                <Label x:Name="fqfs" Foreground="White"/>

            </StackPanel>

            <Button x:Name="Close_b" Grid.Column="1" Width="35" Height="35" HorizontalAlignment="Right" Margin="0,0,20,0" Style="{StaticResource PowerButton}" Click="close_a_Click"/>

            <Button x:Name="Minimize_b" Grid.Column="1" Width="35" Height="35" HorizontalAlignment="Right" Margin="0,0,75,0" Style="{StaticResource MinimizeButton}" Click="minimize_a_Click"/>

            <local:ParametersView Margin="10" Grid.Column="1" Grid.Row="1" x:Name="View" />
            <!--<ContentControl Grid.Column="1" Grid.Row="1" Margin="10" Content="{Binding CurrentView}"/>-->

        </Grid>

    </Border>
</Window>

最初,我使用的是ContentControl,但是由于问题来自上下文,我以更直接的方式进行了测试,但仍然不起作用。

parametersview.xaml

<UserControl x:Class="MVVMTest.ParametersView"
             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:MVVMTest"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800"
             DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}">


    <StackPanel>
        <TextBlock Text="Parameter"
                   Foreground="White"
                   FontSize="30"
                   HorizontalAlignment="Left"
                   Margin="0,0,0,20"
                   FontFamily="Century Gothic"/>

        <StackPanel Orientation="Horizontal">

            <Button x:Name="Export" Content="Save" Width="250" Height="40" Background="#01202f" Foreground="White" Style="{StaticResource ParameterButton}"/>
            <Button x:Name="Import" Content="Load" Width="250" Height="40" Background="#01202f" Foreground="White" Style="{StaticResource ParameterButton}" Margin="20,0,0,0"/>
        
        </StackPanel>

        <Label x:Name="dataCOntextLabel" Foreground="White"/>
    </StackPanel>
</UserControl>

我尝试使用DataContext相对于父级,但它仍然不起作用,我使用标签(MainWindow中的FQFS和Parameterview中的DataContextLabel)来查看每个DataContext,FQFS,FQFS显示我想要的东西,但DataContext保持空。

但是,由于我的观点被定义为MainWindows的孩子,因此我什至不必在参数视图中精确地确定DataContext,但它仍然不起作用。

我确切地来可以默认情况下所有.cs文件仍然是:

fqfs.content = this.datacontext;(mainwindow.xaml.cs) dataContextLabel.content =“ dataContext =” + this.datacontext;(parametersview.xaml.cs)

mainviewmodel.cs也很空,但是由于我从不参考任何视图的更改,因此不应该拥有它任何影响。

尽管我在互联网上的大多数问题都在我自己搜索了一段时间,但似乎我真的无法弄清楚这里有什么问题,但如果有人对此问题有解决方案,我将非常感谢它。

编辑1: 我之所以尝试这是因为我需要了解如何在更大的项目中正确设置DataContext(我也有这个问题),问题是该项目有点复杂,因此我选择在在尝试在较大的项目中实施它之前,一个新的(和较小)的项目。

我需要MainWindow和Parameterview能够访问相同的数据(例如集合)。因此,他们俩都需要相同的DataContext。

除了您还有contentControl的答案(在mainwindows.xaml中使用评论),它也确实很有帮助,因为我稍后要使用它来进行动态视图。

预先感谢。

parameterview.xaml.cs

namespace MVVMTest
{
    /// <summary>
    /// Interaction logic for ParametersView.xaml
    /// </summary>
    public partial class ParametersView : UserControl
    {
        public ParametersView()
        {
            InitializeComponent();

            dataCOntextLabel.Content = "DataContext = " + this.DataContext;
        }
    }
}

mainwindow.xaml.cs

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            View.DataContext = this;

            fqfs.Content = this.DataContext;
        }

I ask this question after searching though a lot of solution and none of them worked,

My problem can be resumed this way: I have a main window (MainWindow.xaml), I have a view (ParametersView.xaml).

I also have the MainViewModel.cs file that would be my DataContext common to both view.

First I would like to make the parameter view inherit the DataContext from the MainWindows view, which is MainViewModel.

MainWindow.xaml

<Window x:Class="MVVMTest.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:MVVMTest"
        mc:Ignorable="d"
        WindowStyle="None"
        AllowsTransparency="True"
        Background="Transparent"
        Title="MainWindow" Height="450" Width="800">

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

    <Border Background="#272537"
            CornerRadius="35">

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>
                <RowDefinition Height="70"/>
                <RowDefinition/>
            </Grid.RowDefinitions>

            <StackPanel Grid.Row="1">

                <RadioButton Content="Acquisition"
                             Height="50"
                             Foreground="White"
                             FontFamily="Century Gothic"
                             FontSize="20"
                             Style="{StaticResource MenuButtonTheme}"
                             />

                <RadioButton Content="Data visualization"
                             Height="50"
                             Foreground="White"
                             FontFamily="Century Gothic"
                             FontSize="20"
                             Style="{StaticResource MenuButtonTheme}"
                             Command="{Binding DataVisuViewCommand}"/>

                <RadioButton Content="Parameter"
                             Height="50"
                             Foreground="White"
                             FontFamily="Century Gothic"
                             FontSize="20"
                             Style="{StaticResource MenuButtonTheme}"
                             IsChecked="True"
                             Command="{Binding ParameterViewCommand}"/>

                <RadioButton Content="Post processing"
                             Height="50"
                             Foreground="White"
                             FontFamily="Century Gothic"
                             FontSize="20"
                             Style="{StaticResource MenuButtonTheme}"
                             Command="{Binding MembersViewCommand}"/>

                <Label x:Name="fqfs" Foreground="White"/>

            </StackPanel>

            <Button x:Name="Close_b" Grid.Column="1" Width="35" Height="35" HorizontalAlignment="Right" Margin="0,0,20,0" Style="{StaticResource PowerButton}" Click="close_a_Click"/>

            <Button x:Name="Minimize_b" Grid.Column="1" Width="35" Height="35" HorizontalAlignment="Right" Margin="0,0,75,0" Style="{StaticResource MinimizeButton}" Click="minimize_a_Click"/>

            <local:ParametersView Margin="10" Grid.Column="1" Grid.Row="1" x:Name="View" />
            <!--<ContentControl Grid.Column="1" Grid.Row="1" Margin="10" Content="{Binding CurrentView}"/>-->

        </Grid>

    </Border>
</Window>

Initially, I was using ContentControl, but since the problem come from the Context, I tested with a more straightforward way, and it still doesn't work.

ParametersView.xaml

<UserControl x:Class="MVVMTest.ParametersView"
             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:MVVMTest"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800"
             DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}">


    <StackPanel>
        <TextBlock Text="Parameter"
                   Foreground="White"
                   FontSize="30"
                   HorizontalAlignment="Left"
                   Margin="0,0,0,20"
                   FontFamily="Century Gothic"/>

        <StackPanel Orientation="Horizontal">

            <Button x:Name="Export" Content="Save" Width="250" Height="40" Background="#01202f" Foreground="White" Style="{StaticResource ParameterButton}"/>
            <Button x:Name="Import" Content="Load" Width="250" Height="40" Background="#01202f" Foreground="White" Style="{StaticResource ParameterButton}" Margin="20,0,0,0"/>
        
        </StackPanel>

        <Label x:Name="dataCOntextLabel" Foreground="White"/>
    </StackPanel>
</UserControl>

I tried to use the DataContext relative to the parent but it still doesn't work, I use a label (fqfs in MainWindow, and dataCOntextLabel in ParameterView) in order to view each dataContext, fqfs display what I want, but dataCOntext remain empty.

But since my view is defined as a children of the mainWindows, I should not even have to precise a DataContext in the Parameter view, yet it still doesn't work.

I precise that all the .cs file are still by default except for these two obvious line:

fqfs.Content = this.DataContext; (MainWindow.xaml.cs)
dataCOntextLabel.Content = "DataContext = " + this.DataContext; (ParametersView.xaml.cs)

MainViewModel.cs is also empty, but since I never refer to any change of view, it shouldn't have any impact.

I been though most of the question on the subject on internet and searched by myself for a while but it seems I really can't figure what is wrong here, i would really appreciate it if someone have a solution to this problem.

EDIT 1:
The reason I try this is because I need to understand how to properly set up a DataContext in a bigger project (where I also have this problem), the problem is that the project is a bit complex, so I choosed to find the solution in a new (and smaller) project before trying to implement it in the bigger project.

I need the MainWindow and the ParameterView to be able to access the same data (for instance a collection). So they both need the same dataContext.

Beside, if you have the answer for ContentControl as well (use in comment in MainWindows.xaml), it would be really helpful too as I meant to use that later for dynamic view.

Thank in advance.

ParameterView.xaml.cs

namespace MVVMTest
{
    /// <summary>
    /// Interaction logic for ParametersView.xaml
    /// </summary>
    public partial class ParametersView : UserControl
    {
        public ParametersView()
        {
            InitializeComponent();

            dataCOntextLabel.Content = "DataContext = " + this.DataContext;
        }
    }
}

MainWindow.xaml.cs

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            View.DataContext = this;

            fqfs.Content = this.DataContext;
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白色秋天 2025-01-24 21:54:56

MainWindow 中保留以下内容:

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

删除对 DataContext 的所有其他引用。例如,在 MainWindow() 构造函数中,删除除 InitializeComponent() 之外的所有内容。从 ParametersView.xaml 中的 UserControl.DataContext 中删除。

子控件始终继承父DataContext。您必须做的是为相关视图模型属性提供以点为前缀的路径。

In MainWindow keep this:

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

Remove all other references to DataContext. For example, in MainWindow() constructor, remove everything except InitializeComponent(). Remove from the UserControl.DataContext in ParametersView.xaml.

Child controls always inherit the parent DataContext. What you must do is provide dot-prefixed paths to your relevant viewmodel properties.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文