C# 处理多个下拉选择的更好方法

C# 处理多个下拉选择的更好方法,c#,.net-2.0,c#-2.0,asp.net-2.0,observer-pattern,C#,.net 2.0,C# 2.0,Asp.net 2.0,Observer Pattern,我有多个下拉菜单。我添加了代码,但目前,它完全驻留在代码隐藏文件中。我想使用任何设计模式,以一种简单和整洁的方式处理各种选择 报告生成标准的编制如下: 报告类型下拉选项包括: 方案类型 方案方面 地区层面 分块 全部 默认情况下,仅启用第一个下拉列表。从该下拉列表中选择一个选项,将启用相应的下拉列表 不仅如此,Scheme、District和Block下拉列表的值在使用AJAX从这些下拉列表或Scheme Type下拉列表中选择项目时也会发生变化 它通常涉及各种SQL查询和启用/禁用下拉列表。我

我有多个下拉菜单。我添加了代码,但目前,它完全驻留在代码隐藏文件中。我想使用任何设计模式,以一种简单和整洁的方式处理各种选择

报告生成标准的编制如下:

报告类型下拉选项包括:

  • 方案类型
  • 方案方面
  • 地区层面
  • 分块
  • 全部
  • 默认情况下,仅启用第一个下拉列表。从该下拉列表中选择一个选项,将启用相应的下拉列表

    不仅如此,
    Scheme
    District
    Block
    下拉列表的值在使用AJAX从这些下拉列表或
    Scheme Type
    下拉列表中选择项目时也会发生变化

    它通常涉及各种SQL查询和启用/禁用下拉列表。我现在的代码已经被许多
    IF
    EndIfs
    弄得乱七八糟

    我想知道是否可以使用
    观察者模式
    或任何使用
    的方法来简化此操作。有没有办法让这个多重选择和下拉列表的填充变得易于管理和简单

    以下编辑以明确要求

    让我进一步澄清

    第一个下拉菜单是键下拉菜单,在页面打开时默认启用。默认情况下,将禁用所有其他下拉列表。但这并不意味着级联下拉列表是正确的选择,因为子下拉列表中的选择是随机的

    整个计划是以可理解的形式为每个下拉列表简化代码。根据选择,有许多Ifs和ELSEIF用于选择正确的查询

    例如:用户从报告类型主下拉列表中选择,
    District-wise report
    。在这种情况下,将启用三个子下拉列表,即

    Scheme Type
    
    Scheme
    
    District
    
    如果用户从“方案类型”列表中选择“全部”,则在“方案”下拉列表中填写所有类别中的所有方案类型

    如果用户从选项中选择了特定的方案类型:城市、农村或其他,则方案下拉列表将过滤方案的名称

    现在,Scheme下拉列表还有一个选项ALL。用户可以选择全部或选择任何特定方案

    地区也是如此。如果选择“全部”,则“方案”下拉列表中的方案将获取所有地区的所有方案,但如果选择了特定地区,则“方案”下拉列表必须填充该地区的过滤方案

    请注意,在这种情况下,我们现在以相反的顺序移动,因为地区下拉列表再次过滤方案下拉列表

    这同样适用于“块”下拉列表

    除所选选项外,还有多种条件需要检查。假设用户没有选择任何选项,或者用户选择了所有选项

    我想用每个下拉列表的名称创建单独的类。这些类应该不断听取下拉列表中任何更改的通知(观察者)


    我想我可以澄清一下。

    如果我正确理解了您的范例,实际上,您有一个下拉列表(报告类型),用于确定是否按方案类型、方案、地区或街区(或以上所有)进行选择。如果您没有“全部”选项,我建议您要么只使用两个下拉列表(一个用于报告类型,另一个用于标签更改以匹配),要么取消“报告类型”下拉列表,并在其他每个下拉列表旁边放置一个单选按钮以选择所需的。当包含“全部”选项时,您可能不会使事情复杂化太多;例如,您可以再添加一个单选按钮并启用所有四个下拉列表

    但是,您会询问观察者模式。从中,观察者模式在以下情况下非常有用:

  • 抽象有两个方面,一个依赖于另一个
  • 更改一个对象需要更改其他对象,而您不知道需要更改多少个对象;或
  • 对象应该能够通知其他对象,而无需假设这些对象是谁
  • 我不完全确定这些情况是否适用于这里。第二种情况与您的问题有一些相似之处,但您确实知道需要更改什么以及如何更改。如果您正在进行的唯一更新是按报告类型进行的,那么只需启用或禁用右下拉菜单即可。但是,您说其他下拉列表可能在“全部”选项中相互影响。即使在这种情况下,我也不确定观察者模式本身是否最有用。由于您使用SQL填充下拉列表,我猜您可能使用了许多不同的存储过程(或特殊查询),具体取决于您需要的参数。我的建议是,每个下拉列表只有一个查询,明智地使用
    NULL
    。例如,要从其他值填充块,可能需要:

    CREATE PROCEDURE GetBlocks
    (
        @SchemeTypeId INT NULL,
        @SchemeId INT NULL,
        @DistrictId INT NULL
    )
    AS
    SELECT b.BlockId, b.BlockName
    FROM   Blocks b
    INNER JOIN SchemeTypeBlocks stb ON b.BlockId = stb.BlockId
    INNER JOIN SchemeBlocks sb ON b.BlockId = sb.BlockId
    INNER JOIN DistrictBlocks db ON b.BlockId = db.BlockId
    WHERE  (@SchemeTypeId IS NULL OR stb.SchemeTypeId = @SchemeTypeId)
    AND    (@SchemeId IS NULL OR sb.SchemeId = @SchemeId)
    AND    (@DistrictId IS NULL OR db.DistrictId = @DistrictId)
    ORDER BY b.BlockName
    
    在不了解您的数据库的情况下,我不知道确切的工作方式,但我的想法是,对于您尚未选择的任何内容,您只需传递
    NULL
    。这可能会稍微简化您的代码


    如果这还不能回答您的问题,请让我知道我可以澄清什么。

    既然您似乎可以使用Javascript完成所有客户端操作,为什么您要查询这么多数据库?您应该持久化数据客户端和服务器端。您可以调用所有相关的下拉数据,对其进行缓存,然后从客户端调用一个WebMethod,该WebMethod将返回包含所需数据的JSON。对于服务器端对象持久性,您应该查看EntityFramework4.1,其中每个对象都是表的表示

    我会将jQuery与Knockout JS结合使用,或者只使用jQuery,使用JSON在客户端持久化数据,无需返回和转发到sql server

    下面是一个很好的击倒JS的例子。
    <ajaxToolkit:CascadingDropDown ID="ddlReportType" runat="server" TargetControlID="ddlSchemeType" Category="SchemeType" PromptText="Please select a ReportType" LoadingText="[Loading Report Types...]" ServicePath="ReportService.asmx" ServiceMethod="GetDropDownReportTypeContents" ParentControlID="DropDownList1" SelectedValue="SomeValue" />
    [System.Web.Services.WebMethod]
    [System.Web.Script.Services.ScriptMethod]
    public CascadingDropDownNameValue[] GetDropDownReportTypeContents(
           string knownTypeValues, string typevalue) { ... }
    
        string query = "SELECT * FROM Reports";
        List<string> filters = new List<string>();
        bool ReportType = true;
        bool SchemeType = true;
        bool Scheme = true;
        bool District = true;
        bool Block = true;
    
        if (ReportType)
            filters.Add("ReportType = true");
        if (SchemeType)
            filters.Add("SchemeType = true");
        if (Scheme)
            filters.Add("Scheme = true");
        if (District)
            filters.Add("District = true");
        if (Block)
            filters.Add("Block = true");
    
        if (filters.Count() > 0)
        {
            query = query + " WHERE " + string.Join(" AND ", filters.ToArray());
        }
    
    $('#' + target.attr('cascading-dependson')).change(function () {
            if($(this).find("option:selected").val() == $(target).attr("id")){ // this is added if
                $(target).removeAttr("disabled");  // added
                selectFromAjax($(target).attr('cascading-loadfrom'),
                { id: $(this).find("option:selected").val() },
                target);
            }
            else {  //added
                $(target).attr("disabled", "disabled");
            }
        });
    
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate><asp:DropDownList id="firstDrpDown" AutoPostBack="true"  
     OnSelectedIndexChanged="firstDropDown_SelectedIndexChanged"AppendDataBoundItems="true"
       name="firstDropDown" runat="server">
    
    <asp:DropDownList id="scndDrpDown" **AutoPostBack="true"**  
    OnSelectedIndexChanged="scndDropDown_SelectedIndexChanged" AppendDataBoundItems="true"   
    name="scndDropDown" runat="server" > 
    
     </ContentTemplate>
      <asp:UpdatePanel>