从外部对象管理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();
    }
}

如果可能的话,这会是一种糟糕的做法吗?

从外部对象管理wpf-windows

虽然我不太清楚你试图实现的目标是否有意义,但这里有一个可能的解决方案(假设你可以配置你需要的规则)。

首先,我们有一个可配置的"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();
    }
}

如果逻辑更复杂,或者不仅仅取决于业务对象本身的状态,则需要进行一些调整以将其考虑在内。