从父ViewModel设置的WPF -Child datacontext不包含父ViewModel中的修改值

时间:2017-12-07 10:29:02

标签: wpf mvvm user-controls

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

父虚拟机 ChildUserControlVM ChildVM = new ChildUserControlVM(ParentModel.ChildModel);

MainWindow.xaml

但是这种方法不起作用,因为我没有在子视图中获得父视图模型中设置的值,反之亦然。

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

我需要一些解决方案,以便我可以在用户控件中使用MVVM,同时确保数据从父级传递到子级,反之亦然。 在usercontrol中,我将有一些按钮,我想通过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}">

3 个答案:

答案 0 :(得分:1)

父视图模型应包含子视图模型作为属性,如

public class ParentViewModel
{
    public ChildViewModel1 ChildViewModel1 { get; set; }
    public ChildViewModel2 ChildViewModel2 { get; set; }
}

您的UserControl不应该有自己的任何视图模型。相反,他们应该公开依赖属性,如

public partial class MyView1 : UserControl
{
    public string MyProperty { get; set; } // this must be a dependency property
}

可以在使用UserControl时绑定,例如在你的MainWindow的XAML中,比如

<MyView1 MyProperty="{Binding ChildViewModel1.SomeProperty}" />

如果有许多可绑定属性,您可以将UserControl的DataContext设置一次到适当的子视图模型:

<MyView1 DataContext="{Binding ChildViewModel1}"
         MyProperty="{Binding SomeProperty}" />

答案 1 :(得分:0)

在xaml中设置每个usercontrol的datacontext

<UserControl.DataContext>
    <VMPath:ChildVM/>
</UserControl.DataContext>

然后为MainWindow中定义的用户控件添加加载的事件

<ViewPath:MyUserControl x:Name="uc1" Loaded="UserControlLoaded"/>
在您的代码背后

    private void UserControlLoaded(object sender, RoutedEventArgs e)
    {
        ParentVM vm = this.DataContext as VM;
        ChildVM cvm = uc1.DataContext as ChildVM;
        // do your stuff
    }

如果您需要执行的操作始终相同,则可以对所有UserControl使用1方法。

基本上你要做的是以下操作。

  • 将用户控件的dantacontext静态设置为“空”ChildVM的实例

  • 加载您的控件

  • 加载后
  • 执行你需要在ChildVM上进行的操作(比如设置一些属性)

所有这些都可以在您真正使用您的应用之前

答案 2 :(得分:0)

我的理解就像您需要从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"); }
    }

}

Child Usercontrol View模型:

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>