我有一个应用程序,其中一个部分包含一组循环中的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();
}
}
}
通过新的更改,而不是始终是W1 - > W2 - > W3 - > W1,取决于业务对象的信息,每次迭代有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();
}
}
如果可能,这将是一个不好的做法?
答案 0 :(得分:0)
虽然我不太清楚你想要实现的目标实际上有多大意义,但这里有一个可能的解决方案(假设你可以配置你需要的规则)。
首先,我们有一个可配置的“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();
}
}
如果逻辑更复杂,或者不仅仅依赖于业务对象本身的状态,则需要进行一些调整以将这些考虑在内。