各位高人:
菜鸟一枚,请问如下问题:
工具栏上有一个确定按钮,在不同的子窗口下,点击“确定”按钮实现不同的处理。即:同一个确定按钮如何处理,在不同的子窗口界面下的情况。举例如:
如果当前激活子窗口为“查询工单”,我点击确定,就调用相应的函数查询工单;若当前激活子窗口为“查询客户”,就去查客户。
如果用类似if。。else的语句似乎能处理,总觉不太好,是否有更好的处理模式?请高人出手!
菜鸟一枚,请问如下问题:
工具栏上有一个确定按钮,在不同的子窗口下,点击“确定”按钮实现不同的处理。即:同一个确定按钮如何处理,在不同的子窗口界面下的情况。举例如:
如果当前激活子窗口为“查询工单”,我点击确定,就调用相应的函数查询工单;若当前激活子窗口为“查询客户”,就去查客户。
如果用类似if。。else的语句似乎能处理,总觉不太好,是否有更好的处理模式?请高人出手!
2.每个子窗体继承BaseChildForm,重写ButtonClick方法,内容为“确定"按钮点击事件内容
3.在父窗体中的”确定“按钮事件中写baseChildForm.ButtonClick();//baseChildForm为子窗体类对象
我当前菜单是:
Menu currentMenu = Menu.Menu1;
在不使用委托的时候你需要写if else或者switch语句:
static void TestWithoutDelegate(Menu menu)
{
switch (menu)
{
case Menu.Menu1:
Console.WriteLine("菜单1");
break;
case Menu.Menu2:
Console.WriteLine("菜单2");
break;
case Menu.Menu3:
Console.WriteLine("菜单3");
break;
default:
break;
}
}
然后调用之:
TestWithoutDelegate(currentMenu);如果使用委托,那么你就需要多写几个方法,类似于:
static void Menu1()
{
Console.WriteLine("菜单1");
} static void Menu2()
{
Console.WriteLine("菜单2");
} static void Menu3()
{
Console.WriteLine("菜单3");
}
然后客户端点击了哪个菜单,就使用委托来调用,类似于:
static void TestWithDelegate(Test del)
{
del();
}
Test test = Menu1;
TestWithDelegate(test);
问些比较菜的问题。
当某个子窗体被激活时,就调用相应子窗体的处理函数。那这个激活,是.net框架或者操作系统自动将BasechildForm 实例化为那个窗体了?
思来想去,不知道是谁让该类的多态性完成了这个操作。
1.兄的方法似乎是类似于事件处理。具体一下场景:主窗体工具栏按钮上有个“执行”按钮,当不同的子窗体激活时,执行相应子窗体的功能。 于是代码示例如下:
主窗体:Main
1。定义委托 public delegate void ExecuteEventHandler(object sender, EventArgs e);
2. 定义事件
public event ExecuteEventHandler Execute;
/// 执行按钮事件触发函数
private void OnExecute(EventArgs e)
{
if (this.Execute != null)
this.Execute(this, e);
}
/// 点击“执行”按钮事件,触发执行事件
private void tsBtnExcute_Click(object sender, EventArgs e)
{
EventArgs ee = new EventArgs();
OnExecute(ee);
}
子窗体:侦听事件+处理函数
ExcuteQueryOrder(objest sender, EventArgs e)
{
从 参数e中拆解出主窗体送来的参数,执行查询工单
}
还要在子窗体中为主窗体登记这个处理函数,
Main.Execute += new ExecuteEventHandler(this.ExcuteQueryOrder)
首先请兄看一下这个写法是否正确,菜鸟妄言多有错误。2. 如果上述正确,接下来问题来了,每个子窗体都需要获得主窗体的实例才行,否则无法为主窗体登记事件处理函数。同时,这样用委托的目的不就是减轻耦合么,如果还需要获得主窗体的实例,岂不是有悖于初衷了?3.附加问题,如果子窗体需要工具栏上其他输入框如:Textbox输入的东西,且不同的子窗体需要的参数不尽相同,比如查工单需要日期段,查客户需要编号段,而这些又都在主窗体的工具栏上,该如何传递给子窗体呢?问题有点多,高手们见笑了。
你的问题非常好。我认为这正好说明勤于动手的人,很快就会超过只动嘴不动手的人。实际上,正如你说,所谓“事件”再此处成了一个噱头,把原本不应该“依赖倒置”的关系硬要倒置过来,反而要求“倒置之后再倒置回来”,反而使得原来的干净的分层关系变得乱起来了。回到你的最初的问题我们可以简单地分析名词和动词,看看对象(类)建模。什么是“当前查询子窗口”呢?你可以设计一个接口public interface 当前查询子窗口
{
void Query();
}然后你的主窗口可以判断“当前窗口”是不是查询子窗口,例如var win = ActivedForm as 当前查询子窗口;
if(win!=null)
win.Query();
这样的编程模式,仅仅比所谓的“条件分支、循环语句”稍微复杂一点,只不过这与基本的控制流语句相比稍微接触一点设计,并不复杂。
if(ca !=null)
ca.SetDatas(this.DataA);
var cb = ctrl as IRequireDatasB;
if(cb !=null)
{
cb.SetDatas(this.DataB);
cb.Saved += cb_Saved;
}
var cc = ctrl as IRequireDatasC;
if(cc !=null)
vc.SetDatas(this.DataC, others);
也就是说如果子控件需要什么功能,那么它就让自己实现相应的接口,于是你的主程序就自动跟它协同了。
但对于工具栏上控件的值传入子窗口,还是不甚理解。详细描述一下。
工具栏有若干控件:日期控件、组合框、Checkbox。
子窗口一:只需要日期控件和组合框的内容;
子窗口二:只需要组合框和Checkbox的内容。
需要主窗口获得这些控件的值,通过“执行”按钮传入相应的子窗口。
兄台的下述代码,不是太理解。个人感觉,将所有控件值都作为参数全部传入接口方法似乎是可以的。比如:
ExeCute(DataTime , ComBox, CheckBox)
不同的子窗口在重载Execute时,只需取出自己需要的控件值就可以了。但是,这个方法似乎有些笨拙,如果控件很多呢?好像没有体现出代码的自适应性。不知是否有更好的解决方案,请兄台解惑。
再次拜谢!
1 子窗口都从自定义的 formbase 继承,在 formbase 中写些虚方法,子窗口重载这些方法,点击按钮的时候把子窗口转换成 formbase 就行了。
2 子窗口都实现自定义的 iform 接口,在接口中写方法,子窗口转换成 iform 也行。
另外,如果子窗口转换为相应的父类或者接口为空,则可以禁用按钮,效果最好。
我上面说的例子只是进行了简化,并不是说要用控件作为传入参数。我感觉现在最想不通的就是:
一个UI框架中,主窗体到底如何子窗体交互。这么说似乎有点宽泛,更具体一点就归结为上面的问题,就是当不同的子窗体需要不同的数据参数时,主窗体是可以从控件上获得这些值的,而子窗体是不能的,但是如何传递给子窗体?上面有个兄弟说定义全局变量,这确实是个方法,子窗体是可以获得的,但是全局变量感觉耦合就太强了。
我只是想知道高人们在编写UI框架时,到底是如何设计,怎么让主窗体与子窗体进行交互的。再次拜谢各位的回复!多谢各位的耐心回答。