如何在同一个ViewModel中使用不同的行为?

时间:2013-05-14 08:07:40

标签: wpf oop mvvm

我有为长时间运行的任务设计的视图。它有一个标题和一个进度条。 因此,模型具有标题的文本和进度条和TotalAmountOfWork字段的计数器。该模型也有

public delegate void TaskCompleted(string resultDescription);
public event TaskCompletedCopyingCompletedEvent;
public event Action UpdateViewState;

当计数器更改时,模型会调用UpdateViewState。 ViewModel在视图中订阅了事件和更新。

确定。我有两个类用于将文件从硬盘复制到闪存驱动器,一个类用于诊断信息检索,这些信息最终也应该复制到闪存驱动器中。

我想在同一个ViewModel中使用它们,但我无法弄清楚如何避免代码重复。我无法弄清楚如何依靠适当的面向对象设计。

这三个类可以实现这样的接口:

interface ILongRunningTask {
    void DoWork();
}

然后我可以将ILongRunningTask作为参数实现ViewModel。

但请查看界面名称。它看起来太笼统了。这样的抽象似乎有些不对。

确定。在我看来,ViewModel应该采用委托来调用长时间运行的任务。但在这种情况下,ViewModel将如何与更新其属性的模型进行交互?

//更新 现在,模型看起来像:

public class FilesCopyingModel : IFilesCopier {
    protected int filesCountToCopy;
    public int FilesCountToCopy {
        get { return filesCountToCopy; }
        set {
            filesCountToCopy = value;
            InvokeUpdateViewState();
        }
    }

    protected int currentProgressValue;
    public int CurrentProgressValue {
        get { return currentProgressValue; }
        set {
            currentProgressValue = value;
            InvokeUpdateViewState();
        }
    }

    public delegate void CopyingCompleted(string resultDescription);

    public event CopyingCompleted CopyingCompletedEvent;
    public event Action UpdateViewState;

    private readonly IFilesCopier filesCopier;

    protected FilesCopyingModel() {
    }

    public FilesCopyingModel(IFilesCopier filesCopier) {
        if (filesCopier == null)
            throw new ArgumentNullException("filesCopier");
        this.filesCopier = filesCopier;
    }

    protected static string GetCurrentDateTime() {
        return DateTime.Now.ToString("dd.MM.yyyy hh.mm.ss");
    }

    protected void InvokeCopyCompletedEvent(string resultDescription) {
        if (CopyingCompletedEvent != null)
            CopyingCompletedEvent(resultDescription);
    }

    protected void InvokeUpdateViewState() {
        if (UpdateViewState != null)
            UpdateViewState();
    }

    protected DriveInfo GetFirstReadyRemovableDrive() {
        return
            DriveInfo.GetDrives()
                     .FirstOrDefault(driveInfo => driveInfo.DriveType == DriveType.Removable && driveInfo.IsReady);
    }

    public void Copy() {
        filesCopier.Copy();
    }
}

public interface IFilesCopier {
    void Copy();
}

public class KFilesCopier : FilesCopyingModel, IFilesCopier {
    private string destinationKFilesDirPath;

    public new void Copy() {
       //some code
    }

    private static string ComposeDestinationKFilesDirPath(DriveInfo drive) {
        //some code
    }
}

public class LogsDirCopier : FilesCopyingModel, IFilesCopier {
    public readonly string LogsDirPath;

    public LogsDirCopier() {
        //some code
    }

    public new void Copy() {
        //some code
    }

    private void InternalCopyLogsDir(string destinationPath) {
       //some code
    }

    private static void CloseStorer(ZipStorer zipStorer) {
        //some code
    }

    private static string ComposeDestinationArchiveFilePath(string destinationPath) {
        //some code
    }

    private void DetermineLogFilesCount() {
        //some code
    }

ViewModel与上面的基础架构交互:

public class FilesCopyingViewModel: Screen {       
    private readonly FilesCopyingModel model;
    private readonly IWindowManager windowManager;

    public int CurrentProgress {
        get { return model.CurrentProgressValue; }
    }

    public int FilesCountToCopy {
        get { return model.FilesCountToCopy; }
    }

    [ImportingConstructor]
    public LongRunningViewModel(IFilesCopier copier) {
        model = copier as FilesCopyingModel;
        model.CopyingCompletedEvent += CopyingCompletedHandler;
        model.UpdateViewState += UpdateViewStateHandler;
        windowManager = new WindowManager();
    }

    private void UpdateViewStateHandler() {
        NotifyOfPropertyChange(() => CurrentProgress);
        NotifyOfPropertyChange(() => FilesCountToCopy);
    }

    private void CopyingCompletedHandler(string resultDescription) {
        //some code
    }

    private void RemoveDriveSafely() {
        //some code
    }

    private void PromptEjection(string result) {
        //some code
    }

    private void PromptSuccessEjection() {
        //some code
    }

    private void PromptEjectFlashError() {
        //some code
    }

    protected override void OnActivate() {
        try {
            var copier = (IFilesCopier) model;
            Task.Factory.StartNew(copier.Copy);
        }
        catch (Exception ex) {
            //error handling
        }
    }
}

这两个类使用“Copy”作为方法的名称。现在我想添加一个具有非常相似行为的类,但似乎它的方法应该被命名为“CollectDiagnosticInfo”。或者也许我可以添加一个类DiagnosticInfoCopier:IFilesCopier然后只是做同样的事情。我真的不知道,但第六感表明有某种气味。

0 个答案:

没有答案