1

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

这就是我所拥有的: MainWindow.xaml (在 MainWindow.xaml.cs 中它分配 MainVM 作为它自己的 DataContext)

我还想拥有:ChildWindow.xaml 和准系统 ChildWindow.xaml.cs,ChildVM 位于控件后面。

所以,现在:

  1. 如何弹出ChildWindow并将一些对象传递Data给它 ChildVM
  2. 将结果(真/假)和结果数据(一些复杂对象)返回到MainVM?
  3. 作为奖励,可以在他们正在处理Data的时候观察到变化吗?MainVMChildVM

这是我尝试过的 - 它并不能解决所有问题,但这甚至是正确的方向吗?

  • 对于 (2),我创建了一个Window名为的子类DialogWindow,它具有 3 个 DependencyProperties:(Data用于输入数据)、ResultData(用于输出数据)和ResultValue(用于布尔结果)。
  • ResultData并且ResultValue都由ChildVM使用DialogWindowBinding 设置,当ResultValue设置时,DialogWindow关闭。
  • 目前,ChildWindow从 MainWindow.xaml.cs 启动(出于所有意图和目的) - 有点糟糕。然后我可以传递一些输入数据,如下所示:

    ChildDialogWindow w = new ChildDialogWindow();

    w.Data = myDataObj;

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

我认为避免 MainWindow.xaml.cs 的更好方法可能是某种作为依赖项DialogService传递的方法。MainVM但是,我怎样才能将值传递给ChildVM

4

2 回答 2

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;

}
于 2013-07-20T21:26:56.463 回答
0

我正在使用 ICommand 助手“RelayCommand”,并将 IntPtr 数据类型推送到新的 ViewModel(或使用任何其他对象)。很多千篇一律的东西。

主视图:

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

主视图模型:

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;

新视图 xaml:

<TextBlock Text="{Binding ObjectOffset}"/>
于 2014-09-23T22:01:59.290 回答