WPF MVVM - 视图不从其父窗口继承数据上下文
在搜索很多解决方案后,我问这个问题,但它们都无法使用,
我的问题可以通过这种方式恢复:我有一个主窗口(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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在
MainWindow
中保留以下内容:删除对
DataContext
的所有其他引用。例如,在MainWindow()
构造函数中,删除除InitializeComponent()
之外的所有内容。从ParametersView.xaml
中的UserControl.DataContext
中删除。子控件始终继承父
DataContext
。您必须做的是为相关视图模型属性提供以点为前缀的路径。In
MainWindow
keep this:Remove all other references to
DataContext
. For example, inMainWindow()
constructor, remove everything exceptInitializeComponent()
. Remove from theUserControl.DataContext
inParametersView.xaml
.Child controls always inherit the parent
DataContext
. What you must do is provide dot-prefixed paths to your relevant viewmodel properties.