从ShowDialog获取结果而不诉诸代码

时间:2014-06-20 00:33:49

标签: c# wpf mvvm-light

我正在通过对这个问题WPF + Castle Windsor + MVVM: Locator-DataContext的优秀答案实施代码。我不确定如何从ShowDialog()获得价值但不使用后面的代码(打破了可测试性),任何人都有任何想法?

我在MVVM Light Messenger类中使用此类并且它工作正常,但需要使用Service Locator反模式。

修改

我目前无法使用的代码是

DataSourcePicker.xaml.cs

public DataSourcePicker(IDataSourcePickerViewModel viewModel)
{
    InitializeComponent();
    _viewModel = viewModel;
    DataContext = viewModel;
    Closed += (s, a) => RaiseDismissed();
}

public event Action OnDismissed;

private void RaiseDismissed()
{
    if (OnDismissed != null)
        OnDismissed()
}
DataSourcePicker.xaml中的

<Button IsDefault="True" .../>
MainViewModel.cs中的

public void NewDataSource()
{
    var viewModel = _dspViewModelFactory.ResolveDataSourcePickerViewModel();
    var view = _dspFactory.ResolveDataSourcePicker(viewModel);
    view.OnDismissed += () => NewDataSourceImplementation(viewModel);
    view.ShowDialog();
}

当用户点击按钮时,我需要一些方法将DataSourcePickerViewModel上的IsAccepted属性设置为true

1 个答案:

答案 0 :(得分:1)

因为您忽略了显示“ShowDialog”的实现或解释了您的DataSourcePicker如何在应用程序中显示,所以很难给出一个明确的解决方案;因此,根据您对DataSourcePicker的实施情况,这里有两个选项:

如果您的DataSourcePicker.ShowDialog方法仅调用MessageBox.Show,则您的解决方案很简单。

    public void NewDataSource()
    {
        var viewModel = _dspViewModelFactory.ResolveDataSourcePickerViewModel();
        var view = _dspFactory.ResolveDataSourcePicker(viewModel);
        var result = view.ShowDialog();
        if (result.HasValue)
        {
            viewModel.IsAccepted = result.Value;
        }
    }

但是,如果您已将DataSourcePicker实现为自定义模式对话框窗口,或者在ShowDialog执行后不立即关闭对话框窗口,则解决方案会变得更加复杂。

在这种情况下,您必须在视图模型中添加ICommand

class DataSourcePickerViewModel : IDataSourcePickerViewModel
{
    public bool IsAccepted { get; set; }
    public ICommand NewDataSourceCommand { get; private set; }

    public DataSourcePickerViewModel()
    {
        NewDataSourceCommand = new RelayCommand(() =>
        {
            IsAccepted = true;
        });
    }
}

然后,您必须使用以下内容更新DataSourcePickerView

<Button Command="{Binding NewDataSourceCommand}"
        Content="Close"/>

否则,您将需要使用以下解决方案之一将命令绑定到事件:

然后,您将更新视图(如果使用AttachedCommandBehavior库):

<ModalControl x:Class="_24318313.DataSourcePicker"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:local="clr-namespace:_24318313"
              mc:Ignorable="d" d:DataContext="{d:DesignInstance local:DataSourcePickerViewModel}"
              local:CommandBehavior.Event="Close"
              local:CommandBehavior.Command="{Binding NewDataSourceCommand}"
              d:DesignHeight="300" d:DesignWidth="300"/>

如果您认为这不能解决您的问题,请告知我们,我会根据您的反馈进行更新;否则,请将答案标记为已接受。