从ShowDialog获取结果,而无需求助于背后的代码 [英] Getting result from ShowDialog without resorting to code behind
问题描述
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?
我在MVVM Light Messenger
类中使用了该类,并且运行良好,但是需要使用Service Locator反模式.
I was using this class with the MVVM Light Messenger
class and it was working fine, but entails using the Service Locator anti-pattern.
编辑
我当前无法使用的代码是
The current code I have that isn't working is
DataSourcePicker.xaml.cs
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
in DataSourcePicker.xaml
<Button IsDefault="True" .../>
在MainViewModel.cs
in MainViewModel.cs
public void NewDataSource()
{
var viewModel = _dspViewModelFactory.ResolveDataSourcePickerViewModel();
var view = _dspFactory.ResolveDataSourcePicker(viewModel);
view.OnDismissed += () => NewDataSourceImplementation(viewModel);
view.ShowDialog();
}
我需要一些方法来在用户单击按钮时将DataSourcePickerViewModel的IsAccepted属性设置为true
I need some way to set the IsAccepted property on the DataSourcePickerViewModel to true when the user clicks the button
推荐答案
由于您忽略了显示"ShowDialog"的实现或解释了DataSourcePicker
在应用程序中的显示方式,因此很难给您一个清晰的提示.解决方案;因此,根据您对DataSourcePicker
的实现,有两种选择:
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
:
在您的DataSourcePicker.ShowDialog
方法仅调用MessageBox.Show
的情况下,您的解决方案很简单.
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;
}
}
但是,如果您已经将DataSourcePicker
实现为自定义的模态"对话框窗口,或者在执行ShowDialog
之后没有立即关闭对话框窗口,则解决方案将变得更加复杂.
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.
在这种情况下,您将必须在视图模型中添加ICommand
.
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;
});
}
}
然后,您将必须使用以下内容更新DataSourcePickerView
:
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
然后,您将像这样更新视图(如果使用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.
这篇关于从ShowDialog获取结果,而无需求助于背后的代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!