我正在WPF应用程序中,用户可以通过在UI上按下按钮来启动进程。用户可能会被提示一系列必须执行的操作来完成该过程。该视图负责传递初始请求以启动到域的过程。该视图还负责显示用户必须执行的完成该过程的步骤。另一方面,该领域对于解决用户必须执行的步骤是正确的响应。该域还能够检测用户何时完成了请求的步骤。从域传递请求到查看
如果用户启动一个进程,并且该进程要求他们执行一些物理操作,那么我想要一个盒子弹出一条消息来描述他们必须执行的操作。当动作完成后,它会被域检测到,并且窗口应该自动关闭。
将视图向下传递到域的请求很简单。我使用wpf ICommand模式执行此操作。它将信息传递给另一种我发现具有挑战性的方式。我知道绑定和INotifyProperyChanged接口,但我不觉得这是适合我所要做的。
所以,这里是我的初步尝试...
该接口由视图实现,消耗的域。它允许域与用户通信;
public interface IUserRequestMedium
{
/// <summary>
/// Ask the user to perform an action. User does
/// not need to provide any feedback via the user
/// interface, since it is possible for the
/// application to detect when the action has been
/// carried out by the user. The dialog will be closed
/// when either the requested action has been detected,
/// or the user aborts.
/// </summary>
/// <param name="message">
/// Request to be displayed to the user.
/// </param>
/// <param name="userAbortCallback">
/// Callback invoked by the view when the user cancels
/// the request.
/// </param>
/// <param name="actionDetectedCallback">
/// Callback invoked by the domain to confirm the
/// that the requested action has been completed.
/// </param>
void AskUserToPerformDetectableAction(
string message, Action userAbortCallback,
out Action actionDetectedCallback);
}
这是查看代码隐藏。这些代码中的一部分来自Web上的教程(并随后发生了破坏)。这不起作用,但我希望它能传达我的意图。
public partial class MainWindow : Window, IUserRequestMedium
{
// Constructor and other stuff...
public void AskUserToPerformDetectableAction(
string message, Action userAbortCallback,
out Action actionDetectedCallback)
{
Action closeWindow;
NewWindowThread(
() => new ActionRequestBox(message, userAbortCallback),
out closeWindow);
actionDetectedCallback = closeWindow;
}
private Window newWindow;
private void NewWindowThread(
Func<Window> construction,
out Action closeWindow)
{
var thread = new Thread(() =>
{
newWindow = construction();
newWindow.Show();
newWindow.Closed += (sender, e) => newWindow.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
Window rememberedWindow = newWindow;
closeWindow =() =>
{
if (rememberedWindow != null)
rememberedWindow.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal,
new Action(Close));
};
}
}
下面是来自域的使用示例;
public class SomeDomainClass
{
IUserRequestMedium userRequestMedium; // assume this has been assigned in constructor
private Action notifyUserOfActionDetected;
public void PerformSomeProcess()
{
bool processCannotBeCompletedWithoutPowerCycle = ...; // some logic
if (processCannotBeCompletedWithoutPowerCycle)
{
userRequestMedium.AskUserToPerformDetectableAction(
"Please cycle the power on the external device",
CancelProcess,
out notifyUserOfActionDetected);
}
}
public void CancelProcess()
{
// User doesn't want to perform the required action
// so process must be aborted...
}
private void OnPowerCycleDetected()
{
notifyUserOfActionDetected();
}
}
我该如何做这项工作?这是跨线程方面,我陷入了。当域被检测到动作时,我没有成功地让窗口自动关闭。
或者,向后退一步,是否有更好的方法来解决这个问题?