2014-07-11 66 views
0

我想在我的WPF應用程序中實現MVVM體系結構,並且希望能夠在執行命令後修改模型。請注意,我沒有使用任何類型的MVVM框架。從命令中返回一個值?

我有一個基類的命令如下:

namespace MyApplication.Commands { 
    public abstract class CommandBase : ICommand { 
     protected static BackgroundWorker Worker = new BackgroundWorker(); 
     protected static string _result; 

     public string Result { 
      get { 
       return _result; 
      } 
      set { 
       _result = value; 
      } 
     } 

     public abstract void DoWork(DoWorkEventArgs args); 

     public virtual void Execute(object parameter) { 
      Worker = new BackgroundWorker(); 

      Worker.DoWork += (o, args) => DoWork(args); 
      Worker.RunWorkerCompleted += (sender, args) => { 
       RaiseCanExecuteChanged(EventArgs.Empty); 
      }; 
      Worker.ProgressChanged += (sender, args) => { 
       RaiseCanExecuteChanged(EventArgs.Empty); 
      }; 

      Worker.WorkerReportsProgress = true; 

      Worker.RunWorkerAsync(parameter); 
     } 

     public virtual bool CanExecute(object parameter) { 
      return !Worker.IsBusy; 
     } 

     public event EventHandler CanExecuteChanged; 

     protected virtual void RaiseCanExecuteChanged(EventArgs e) { 
      CanExecuteChanged(this, e); 
     } 
    } 
} 

我有一個實現這個我實際的命令,如下所示:

namespace MyApplication.Commands { 
    internal class DoSomethingCommand : CommandBase { 

     public override void DoWork(DoWorkEventArgs args) { 
      Worker.ReportProgress(0); 
      var success = false; 
      try { 
       var parameter = args.Argument as int?; 

       success = DoSomething(parameter); 
      } finally { 
       args.Result = success; 
      } 
     } 

     private static bool DoSomething(int parameter) { 
      // Do something expensive here... 
      System.Func func = (arg) => { 
       Thread.Sleep(arg); 
       return true; 
      }; 

      // etc etc... 

      var success = func.Invoke(parameter); 
      return success; 
     } 
    } 
} 

我用這個作爲在維持MVVM模型的同時執行昂貴操作的方式。我必須在進度和完成事件中執行RaiseCanExecuteChanged,否則UI將不會更新相應的按鈕狀態。

但是,現在我想修改當前被訪問的Model的一個屬性(在ListView控件中選擇了另一個屬性),該屬性作爲ViewModel的屬性公開。我如何在保持MVVM架構的同時做到這一點?

還有什麼更好的方式將ViewModel的當前狀態傳遞給我的命令?目前,我正在使用MultiBinding加上IMultiValueConverter,只允許傳遞object[]

回答

1

爲什麼不在您的命令的構造函數中傳遞對您的viewModel的引用,並在本地將其保存在字段中。這樣,你應該能夠使用其暴露的方法和屬性來操作整個viewModel。

關於你提到的第二個問題:

也有通過視圖模型的當前狀態,以我的命令,沒有更好的辦法?

你的命令應該在viewModel中實現,所以你不應該提供viewModel的狀態。如果不是這樣,爲什麼不通過在控件的CommandParameter屬性中傳遞DataContext來傳遞整個viewModel。