Getting result from ShowDialog without resorting to code behind

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-11 17:26:28

问题


I'm implementing code from the excellent answer to this question WPF + Castle Windsor + MVVM: Locator-DataContext. I'm not sure how to get the value from ShowDialog() though without resorting to code behind (which breaks testability), anyone have any ideas?

I was using this class with the MVVM Light Messenger class and it was working fine, but entails using the Service Locator anti-pattern.

EDIT

The current code I have that isn't working is

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()
}

in DataSourcePicker.xaml

<Button IsDefault="True" .../>

in MainViewModel.cs

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

I need some way to set the IsAccepted property on the DataSourcePickerViewModel to true when the user clicks the button


回答1:


Because you have neglected to show your implementation of "ShowDialog" or explain how your DataSourcePicker shows up in the application, it is difficult to give you a clear solution; So, here are two options depending on your implementation of DataSourcePicker:

In the unlikely event that your DataSourcePicker.ShowDialog method simply invokes MessageBox.Show, your solution is simple.

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

However, if you have implemented your DataSourcePicker as a custom Modal dialog window, or you do not close the dialog window immediately after ShowDialog has executed, the solution becomes more complex.

In this scenario, you will have to add an ICommand to your viewmodel.

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

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

Then, you will have to update your DataSourcePickerView with:

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

Otherwise, you will need to Use one of the following solutions for binding commands to events:

  • MVVM Light - EventToCommand
  • MSDN - EventToCommand
  • Marlon Grechs AttachedCommandBehavior

Then, you would update the view like so (If using the AttachedCommandBehavior library):

<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"/>

If you feel this doesn't solve you issue, please let me know and I will update in response to your feedback; Otherwise, please mark an answer as accepted.



来源:https://stackoverflow.com/questions/24318313/getting-result-from-showdialog-without-resorting-to-code-behind

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!