从外部对象管理wpf-windows
本文关键字:wpf-windows 管理 对象 从外部 | 更新日期: 2023-09-27 18:28:27
我有一个应用程序,它的一部分由一组循环中的wpf窗口组成,发送一个业务对象来对模型进行更改。类似这样的东西(不是真正的代码):
class Window1 {
BusinessObject obj;
public Window1 (BusinessObject obj){
this.obj = obj;
}
/* Things showing obj info and modifying it. */
public void on_Button_Next_Click(object sender, EventArgs args){
new Window2(obj).Show();
this.close();
}
}
class Window2 {
BusinessObject obj;
public Window2 (BusinessObject obj){
this.obj = obj;
}
/* Things showing obj info and modifying it. */
public void on_Button_Next_Click(object sender, EventArgs args){
new Window3(obj).Show();
this.close();
}
}
class Window3 {
BusinessObject obj;
public Window3 (BusinessObject obj){
this.obj = obj;
}
/* Things showing obj info and modifying it. */
public void on_Button_Next_Click(object sender, EventArgs args){
if (!obj.Finished) {
new Window1(obj).Show();
this.close();
}
}
}
有了新的更改,根据业务对象的信息,每次迭代有4个不同的路径:W1->W2->W3->W2->W1,或者W1->W2->W3->W1->W2-->W1,所以我需要为每个窗口都有一个类似的状态。
class Window1 {
BusinessObject obj;
public Window1 (BusinessObject obj, int path, int repetition){
this.obj = obj;
}
/* Things showing obj info and modifying it. */
public void on_Button_Next_Click(object sender, EventArgs args){
if (path == 0) {
new Window2(obj).Show();
this.close();
}
if (path == 1 && repetition = 0){
new Window2(obj, path, 0).Show();
this.close();
}
else {
new Window3(obj, path, 1).Show();
this.close();
}
}
}
有没有可能让窗口管理器来控制窗口而不是这样做?像这个
while (true) {
new Window1(obj).Show();
wait(Window1);
new Window2(obj).Show();
wait(Window2);
if (obj.Condition1){
new Window3(obj).Show();
} else {
new Window1(obj).Show();
wait(Window1);
new Window3(obj).Show();
}
}
如果可能的话,这会是一种糟糕的做法吗?
虽然我不太清楚你试图实现的目标是否有意义,但这里有一个可能的解决方案(假设你可以配置你需要的规则)。
首先,我们有一个可配置的"StateMachine",您可以在其中将业务对象的状态耦合到应该创建的下一个窗口。
public class StateMachine
{
private readonly List<Tuple<Predicate<MyBusinessObject>, Func<MyBusinessObject, StateMachine, Window>>> _matchList;
public StateMachine()
{
_matchList = new List<Tuple<Predicate<MyBusinessObject>, Func<MyBusinessObject, StateMachine, Window>>>();
}
public void RegisterState(Predicate<MyBusinessObject> predicate, Func<MyBusinessObject, StateMachine, Window> windowFactory)
{
_matchList.Add(Tuple.Create(predicate, windowFactory));
}
public Window Next(MyBusinessObject currentState)
{
var entry = _matchList.Where(m => m.Item1(currentState)).FirstOrDefault();
if (entry != null)
return entry.Item2(currentState, this);
return null;
}
}
在创建窗口之前,在应用程序初始化时,您创建一个状态机实例并配置您的规则:
public StateMachine InitializeStateMachine()
{
var stateMachine = new StateMachine();
// If condition1 is true open Window2
stateMachine.RegisterState(bo => bo.Condition1, (bo, sm) => new Window2(bo, sm));
// If the sum is more than 12.5 and some value is not 42 open Window3
stateMachine.RegisterState(bo => bo.SomeSum > 12.5 && bo.SomeValue != 42, (bo, sm) => new Window3(bo, sm));
// The answer to life and everything will open Window4
stateMachine.RegisterState(bo => bo.SomeValue == 42, (bo, sm) => new Window3(bo, sm));
// More rules ...
// If no other condition matches, open Window1
stateMachine.RegisterState(bo => true, (bo, sm) => new Window1(bo, sm));
return stateMachine;
}
您的窗口类都需要实现一个构造函数,该构造函数接受业务对象实例和状态机实例。当需要打开一个新窗口时,他们只需要在状态机上调用Next
。
public class Window1 : Window
{
private readonly StateMachine _stateMachine;
private readonly MyBusinessObject _businessObject;
public Window1(MyBusinessObject businessObject, StateMachine stateMachine)
{
_stateMachine = stateMachine;
_businessObject = businessObject;
}
public void on_Button_Next_Click(object sender, EventArgs args)
{
// look ma, no logic ...
var nextWindow = _stateMachine.Next(_businessObject);
if (nextWindow != null)
nextWindow.Show();
this.Close();
}
}
如果逻辑更复杂,或者不仅仅取决于业务对象本身的状态,则需要进行一些调整以将其考虑在内。