将复杂对象传递给子窗口

时间:2013-07-20 15:17:14

标签: wpf mvvm dependency-properties

打开子窗口的正确方法是什么(例如,修改主窗口上的选定项目),牢记MVVM?

以下是我的内容:MainWindow.xaml(在MainWindow.xaml.cs中,它将MainVM指定为自己的DataContext)

我还希望:ChildWindow.xaml和准系统ChildWindow.xaml.cs,ChildVM支持控件。

所以,现在:

  1. 如何弹出ChildWindow并将一些对象Data传递给它 ChildVM
  2. 获取结果(true / false)和结果数据(有些复杂 对象)回到MainVM
  3. 作为奖励,可以观察到Data的变化 在MainVM
  4. 处理ChildVMWindow

    这是我尝试过的 - 它并没有解决所有问题,但这是否是正确的方向?

    • 对于(2),我创建了一个名为DialogWindow的{​​{1}}的子类,它有3个DependencyProperties:Data(用于输入数据),ResultData(用于输出)数据)和ResultValue(对于bool结果)。
    • ResultDataResultValue均由ChildVM DialogWindow使用Binding设置,设置ResultValueDialogWindow关闭
    • 目前,从{MainWindow.xaml.cs启动ChildWindow(出于所有意图和目的) - 有点不好。然后我可以传递一些输入数据,如下所示:

      ChildDialogWindow w = new ChildDialogWindow();

      w.Data = myDataObj;

    所以,现在我需要在ChildVM上有一个属性Data,并在ChildDialogWindow.xaml.cs中设置。再次,使.xaml.cs更厚。

    我认为可能是一种避免使用MainWindow.xaml.cs的更好的方法,它将某种DialogService作为依赖项传递给MainVM。但是,如何将值传递给ChildVM

2 个答案:

答案 0 :(得分:1)

试试这个。 制作DialogService.cs

public class DialogService
{
    public void Show(FrameworkElement view, ChildViewModel ChildVM)
    {
         Window window = new Window();
         window.Content = view;
         window.DataContext = ChildVM;

         // For closing this dialog using MVVM
         ChildVM.RequestClose += delegate
         {
            window.Close();
         };

         window.Show();
    }
}

现在在ChildVm类中,添加此

public ICommand CloseCommand
    {
        get
        {
            if (_closeCommand == null)
                _closeCommand = new RelayCommand(param => this.OnRequestClose());

            return _closeCommand;
        }
    }

    public event EventHandler RequestClose;

    void OnRequestClose()
    {
        EventHandler handler = this.RequestClose;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }

现在,这是启动此

的方式
public void OpenChildDailog()
    {
    DialogService service = new DialogService();
    ChildViewModel childVM = new ChildViewModel();
    childVM.Data = ; // Assign whatever you want
    childVM.ResultData = ; 

    service.Show(new ChildView(), childVM);

    // Now get the values when the child dailog get closed

    var retVal = childVM.ResultValue;

}

答案 1 :(得分:0)

我正在使用ICommand帮助程序“RelayCommand”,并将IntPtr数据类型推送到新的ViewModel(或使用任何其他对象。)大量的cookie切割器。

主要观点:

<Button Command="{Binding DataContext.ShowObjectInfoCommand}" CommandParameter="{Binding ObjectOffset}" Content="{Binding Name}"/>

MainViewModel:

private RelayCommand _showObjectInfoCommand;
public RelayCommand ShowObjectInfoCommand { get { return _showObjectInfoCommand ?? (_showObjectInfoCommand = new RelayCommand(ExeShowObjectInfoCommand)); } set { } } //Draw Specific Item Table
void ExeShowObjectInfoCommand(object parameter)
{
    ViewObjectInfo objInfo = new ViewObjectInfo();
    IObjectOffsetParameter viewModel = objInfo.DataContext as IObjectOffsetParameter;
    viewModel.ObjectOffset = (IntPtr)parameter;
    objInfo.Show();
}

新的ViewModel +界面:

interface IObjectOffsetParameter
{
    IntPtr ObjectOffset { get; set; }
}

class ViewModelObjectInfo : ViewModelBase, IObjectOffsetParameter
{
    public ViewModelObjectInfo()
    {
    }

    private IntPtr _objectOffset; //Entity Offset
    public IntPtr ObjectOffset
    {
        get { return _objectOffset; }
        set { if (_objectOffset != value) { _objectOffset = value; RaisePropertyChanged("Offset"); } }
    }
}

新视图代码隐藏:

InitializeComponent();
ViewModelObjectInfo viewModel = new ViewModelObjectInfo();
this.DataContext = viewModel;

New View xaml:

<TextBlock Text="{Binding ObjectOffset}"/>