首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理图形用户界面应用程序(C++或C#)中的复杂规则

处理图形用户界面应用程序(C++或C#)中的复杂规则
EN

Stack Overflow用户
提问于 2010-03-25 21:10:35
回答 6查看 490关注 0票数 4

我正在处理一个对话框,在启用OK按钮之前,必须满足其中的几个规则。

目前,页面上的任何操作(如输入数据或从下拉列表中选择项目等)都会调用一个名为ProcessEvent()的函数-该函数处理所有逻辑并启用或禁用OK按钮。

我的问题是,我发现很难使规则简明扼要和易于理解。

一些规则可以被对话框上的另一个操作否定,现在我已经结束了到处都是if else语句,或者这些语句很难阅读和遵循&扩展。

下面的代码是问题的简化,但演示得很好。如何更好地处理此问题(如果可能)

代码语言:javascript
复制
bool CWorkstation::ProcessEvent(void)
    {   
        UpdateData();

        CharCount = GetDlgItemInt(IDC_CharCount, NULL, FALSE); //get latest

        if ( IsDlgButtonChecked(IDC_USEDBNAME))
            {   
                if (!IsDlgButtonChecked(IDC_MAXDBNAME))
                    {
                        EnableNext(TRUE);
                    }
            }

        if (IsDlgButtonChecked(IDC_MAXDBNAME) && CharCount)
            {                   
                if (IsDlgButtonChecked(IDC_USEXMLNAME))
                    {
                        if ( PrefixName.IsEmpty() ) 
                            {
                                EnableNext(FALSE);
                            }
                        else
                            {
                                EnableNext(TRUE);
                            }
            }



            }   


        if (IsDlgButtonChecked(IDC_USEXMLNAME) && PrefixName.GetLength() > 1)
            {
                EnableNext(TRUE);
            }



        if  ( IsDlgButtonChecked(IDC_WSAUTONAME) || IsDlgButtonChecked(IDC_RENAMEIFDUP))
            {

            // TRACE("IDC_WSAUTONAME is Checked\n");

            if ( IsDlgButtonChecked(IDC_USEXMLNAME) && PrefixName.GetLength() > 1 ) 

                {   


                if ( IsDlgButtonChecked(IDC_IDC_USESHORTNAME) ) 

                    {

                    EnableNext(TRUE);
                    }

                else if ( IsDlgButtonChecked(IDC_USELONGNAME) )

                    {

                    EnableNext(TRUE);

                    }

                else

                    {
                    EnableNext(FALSE);
                    }



                }


            if ( !IsDlgButtonChecked(IDC_USEPREFIX) )

                {


                if ( IsDlgButtonChecked(IDC_IDC_USESHORTNAME) ||  IsDlgButtonChecked(IDC_USELONGNAME) )

                    {
                    EnableNext(TRUE);
                    }

                }


            return false;


            }

        } 
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-03-25 21:19:04

我会将if/else语句分成多个函数,并对发送给EnableNext的参数执行&=。您应该只调用EnableNext一次。

所以,举个例子:

代码语言:javascript
复制
// in CWorkStation::ProcessEvent
bool enableNext = true; // start with true

enableNext &= Condition1(); // of course pick better names than Condition1
enableNext &= Condition2(); // this is just for an example

EnableNext(enableNext);

其中Condition1()可能是:

代码语言:javascript
复制
bool Condition1()
{
    return (IsDlgButtonChecked(IDC_USEDBNAME) 
         && !IsDlgButtonChecked(IDC_MAXDBNAME));
}

诸若此类。

这里发生的情况是enableNext变量以true开头。然后,您所做的每个&=都意味着如果任何ConditionX()函数返回false,那么enableNext将以false结束。只有在所有条件都为真的情况下,它才会在最后为真。

票数 6
EN

Stack Overflow用户

发布于 2010-03-25 23:01:52

这个问题可以用监听器的概念来解决。

您可以使每个图形用户界面组件都有一个isEnabled()方法,该方法根据某些条件检查其条件。当调用任何更改任何组件状态的操作时,都会在每个图形用户界面组件上调用isEnabled()

通过这种方式,您可以拥有以下声明:

代码语言:javascript
复制
bool CheckBoxComponent::isValid() {
   return isNameFilled() && isEmailChecked();
}

bool OkButton::canSend() {
   return checkBoxName->isValid() && isEmailChecked();
}

然后,在创建GUI组件时,您可以使每个组件通过listener相互连接。

这样,您就有了它们所属的每个组件的规则,并且不会有大量的if语句。

票数 1
EN

Stack Overflow用户

发布于 2010-03-25 21:14:52

尝试将规则制定为状态机可能会有所帮助,但这是否可行取决于它们的性质。在这种方法中,每当用户填写对话框中的某个字段,或选中复选框或其他任何内容时,您都会相应地更新状态机的状态。如果你拥有它,你可以使用Boost.Statechart来实现它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2515722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档