如何正确通知视图图层以打开对话框?

我有一个WPF应用程序,我正在尝试遵守MVVM模式规则。我的一个视图包含按钮:

                <Button
                    Command="{Binding BrowseCommand}"
                    Margin="50,0"
                    Style="{StaticResource CommonButtonStyle}"
                    Width="100"
                    Height="30">
                    <TextBlock
                        Text="Browse"/>
                </Button>

按钮命令调用方法:

private void Browse(object sender)
{

    DialogService.BrowseForDestinationPath(DestinationPath);

}

此方法的主要目的是显示“选择目录对话框”,收集数据并将其返回到视图模型。

    public static class DialogService
    {

        public static event action<string> FolderBrowseRequested;

        ...

        public static void BrowseForDestinationPath(string initialPath)
        {

            FolderBrowseRequested?.Invoke(initialPath);

        }

    }

调用我的DialogService类中定义的事件,并且触发位于对话框代码后面的订户方法:

        protected void OnFolderBrowseRequested(string initialPath)
        {

            string destinationPath = initialPath;
            var browsingDialog = new VistaFolderBrowserDialog();

            if(browsingDialog.ShowDialog(this).GetvalueOrDefault())
            {

                destinationPath = browsingDialog.SelectedPath;
                var dataContext = DataContext as UnpackArchiveWindowViewModel;

                if (dataContext != null)
                    dataContext.DestinationPath = destinationPath;

            }

            DialogService.FolderBrowseRequested -= OnFolderBrowseRequested; //so dumb

        }

问题是我真的不喜欢这种解决方案,我坚信它是不必要的复杂和不雅观的。如何在单击按钮时正确显示对话框,收集一些数据并将其交付给我们的视图模型?我想将View和ViewModel分开,并完全尊重MVVM机制。

wanglili19860813 回答:如何正确通知视图图层以打开对话框?

您首先可以在界面中描述DialogService所需的行为。

public interface IDialogService
{
    void BrowseForDestinationPath(string initialPath);

    event PathSelectedEvent PathSelected;
}
public delegate void PathSelectedEvent(string destinationPath);  

您的ViewModel将包含IDialogService类型的成员并订阅PathSelectedEvent。将使用您的“浏览”方法(使用“命令”调用)来调用BrowseForDestinationPath方法。

然后可以创建一个实现IDialogService的用户控件。您可以通过ViewModels构造函数或如果ViewModel具有类似

的属性来注入
public IDialogService FolderBorwser {get;set;}

这种方法的好处是您的视图模型只知道一个接口。现在,您将创建具体实例的职责委托给其他对象。我建议使用像Unity或MEF这样的注入容器,因为它们可以处理依赖关系的管理和解决。

,

我鼓励您编写自己的逻辑,因为它可以帮助您了解在MVVM中打开对话框的问题,但是,如果碰到一堵砖墙或不想采取简单的方法,则会有一个名为{{ 3}}可以帮助您解决这些问题。

使用该库,您将像这样编写代码。

private void Browse(object sender)
{
  var settings = new FolderBrowserDialogSettings
  {
    Description = "This is a description"
  };

  bool? success = dialogService.ShowFolderBrowserDialog(this,settings);
  if (success == true)
  {
    // Do something with 'settings.SelectedPath'
  }
}
本文链接:https://www.f2er.com/3084405.html

大家都在问