从父ViewModel设置的WPF -hild datacontext不包含父ViewModel中的修改值(WPF -Child datacontext set from the parent ViewModel doesnot contains the modified values in the parent ViewModel)

在我的WPF应用程序中,我有一个MainWindow.xaml,其中嵌入了许多用户控件。 对于主窗口以及用户控件,我都有单独的viewmodel。 在主窗口ViewModel中,我创建了一个子ViewModel的实例,并将其设置为子的datacontext。

父VM ChildUserControlVM ChildVM = new ChildUserControlVM(ParentModel.ChildModel);

MainWindow.xaml

但是这种方法不起作用,因为我没有得到父子viewmodel中设置的值,反之亦然。

相反,如果我将Child模型对象设置为同时工作的父模型的datacontext。

我需要一些解决方案,以便我可以在用户控件中使用MVVM,同时确保数据从父项传递到子项,反之亦然。 在用户控件中,我将有一些按钮,它们的操作要通过ICommand在子Viewmodel中处理。 添加引用 MainWindow.xaml 的代码片段

<Grid Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0"> <local:ProfileIdentitySettings Visibility="{Binding ProfileIdentitySettingsVisibility,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" DataContext="{Binding ChildProfileIdentityVM}"/> </Grid>

MainWindowVM.cs

ProfileIdentitySettingsVM ChildProfileIdentityVM = new ProfileIdentitySettingsVM(DeviceEditorModel.ProfileIdentitySettings);

ProfileIdentitySettings.xaml

DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.MainWindowVM}">

In my WPF application I have a MainWindow.xaml which has many User Controls embedded into it. I have separate viewmodel for both the main window as well as the user controls. In the Main Window ViewModel I create an instance of the child ViewModel and set it as the child's datacontext.

Parent VM ChildUserControlVM ChildVM = new ChildUserControlVM (ParentModel.ChildModel);

MainWindow.xaml

But this approach is not working as I am not getting the values set in the parent viewmodel in the child one and vice versa.

On the contrary, if I set the Child model object as the datacontext from the parent that is working both way.

I need some solution so that I can use MVVM in the user controls also ensuring data gets passed from parent to child and vice versa. In the usercontrol I am going to have some buttons whose action I want to handle in the child Viewmodel through ICommand. Adding the code snippets for reference MainWindow.xaml

<Grid Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0"> <local:ProfileIdentitySettings Visibility="{Binding ProfileIdentitySettingsVisibility,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" DataContext="{Binding ChildProfileIdentityVM}"/> </Grid>

MainWindowVM.cs

ProfileIdentitySettingsVM ChildProfileIdentityVM = new ProfileIdentitySettingsVM(DeviceEditorModel.ProfileIdentitySettings);

ProfileIdentitySettings.xaml

DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.MainWindowVM}">

最满意答案

我的理解就像你需要从MainViewModel设置usercontrol Viewmodel一样。

MainViewModel:

public class MainWindowViewModel : INotifyPropertyChanged, IMainViewModel { public MainWindowViewModel() { this.Collection = new List<string>(); this.Child = new ChildUserControlViewModel(); this.Child.mainViewModel = this; this.Child.TextValue = "Justin"; } private List<string> _Collection; public List<string> Collection { get { return _Collection; } set { _Collection = value; this.OnPropertyChanged("Collection"); } } private string _MainValue; public string MainValue { get { return _MainValue; } set { _MainValue = value; this.OnPropertyChanged("MainValue"); } } private ChildUserControlViewModel child; public ChildUserControlViewModel Child { get { return child; } set { child = value; this.OnPropertyChanged("Child"); } } }

儿童用户控制查看模型:

public class ChildUserControlViewModel : INotifyPropertyChanged { public IMainViewModel mainViewModel = null; public List<string> Collection { get { return this.mainViewModel.Collection; } set { this.mainViewModel.Collection = value; this.OnPropertyChanged("Collection"); } } private string _TextValue; public string TextValue { get { return _TextValue; } set { _TextValue = value; this.mainViewModel.MainValue = value; this.mainViewModel.Collection.Add(value); this.OnPropertyChanged("TextValue"); } } } public interface IMainViewModel { string MainValue { get; set; } List<string> Collection { get; set; } }

视图:

<Grid> <usr:ChildUserControl DataContext="{Binding Child}"/> </Grid>

My Understanding is like you need to set the usercontrol Viewmodel from MainViewModel.

MainViewModel:

public class MainWindowViewModel : INotifyPropertyChanged, IMainViewModel { public MainWindowViewModel() { this.Collection = new List<string>(); this.Child = new ChildUserControlViewModel(); this.Child.mainViewModel = this; this.Child.TextValue = "Justin"; } private List<string> _Collection; public List<string> Collection { get { return _Collection; } set { _Collection = value; this.OnPropertyChanged("Collection"); } } private string _MainValue; public string MainValue { get { return _MainValue; } set { _MainValue = value; this.OnPropertyChanged("MainValue"); } } private ChildUserControlViewModel child; public ChildUserControlViewModel Child { get { return child; } set { child = value; this.OnPropertyChanged("Child"); } } }

Child Usercontrol View model:

public class ChildUserControlViewModel : INotifyPropertyChanged { public IMainViewModel mainViewModel = null; public List<string> Collection { get { return this.mainViewModel.Collection; } set { this.mainViewModel.Collection = value; this.OnPropertyChanged("Collection"); } } private string _TextValue; public string TextValue { get { return _TextValue; } set { _TextValue = value; this.mainViewModel.MainValue = value; this.mainViewModel.Collection.Add(value); this.OnPropertyChanged("TextValue"); } } } public interface IMainViewModel { string MainValue { get; set; } List<string> Collection { get; set; } }

View:

<Grid> <usr:ChildUserControl DataContext="{Binding Child}"/> </Grid>

更多推荐