简体   繁体   中英

Filtering Gridview Results Using Multiple Checkboxes (How to get And/Or statements to work)

So, I have a GridView , "CustomerGridView," and a SqlDataSource , "SqlDataSource1," that pulls the data from my sql table. Now I wanted to add some filtering, so I created a side panel with various options.

My issue is that with my current code, if I select, say Customers that pay monthly, new customers, and also customers that pay semi-annually. It shows me all of these types including active (not new) customers that meet the criteria, instead of showing me only new customers that either pay semi-annually OR monthly.

How can I fix this?

I've tried parentheses and such, but all to no avail; would I just have to create an if for every situation and manually write each filterexpression?

protected void SqlDataSource1_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
    SqlDataSource1.FilterExpression = string.Empty;
    if (MonthlyCheckBox.Checked)
    {

            SqlDataSource1.FilterExpression = "[CustomerSubscriptionType]='Monthly'";
    }
    if (SemiAnnuallyCheckBox.Checked)
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
            SqlDataSource1.FilterExpression += "OR ([CustomerSubscriptionType]='Semi-Annually')";
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerSubscriptionType]='Semi-Annually'";
        }

    }
    if (AnnuallyCheckBox.Checked)
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
            SqlDataSource1.FilterExpression += "OR ([CustomerSubscriptionType]='Annually')";
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerSubscriptionType]='Annually'";
        }
    }
    if (NewCheckBox.Checked)
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
            SqlDataSource1.FilterExpression += " ( OR [CustomerStatus]='Active')";
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerStatus]='New'";
        }

    }
    if (ActiveCheckBox.Checked)
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
            SqlDataSource1.FilterExpression += " OR [CustomerStatus]='Active'";
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerStatus]='Active'";
        }
    }
    if (SuspendedCheckBox.Checked)
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
            SqlDataSource1.FilterExpression += " OR [CustomerStatus]='Suspended'";
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerStatus]='Suspended'";
        }
    }
    if (ResidentialCheckBox.Checked)
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
                SqlDataSource1.FilterExpression += " AND [CustomerType]='Residential' ";
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerType]='Residential'";
        } 
    }
    if (CommercialCheckBox.Checked)
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
            SqlDataSource1.FilterExpression += " AND [CustomerType]='Commercial' ";
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerType]='Commercial'";
        } 

    }
    if (NotInGroupCheckBox.Checked)
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
            SqlDataSource1.FilterExpression += " AND [CustomerGroup]=''";
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerGroup]=''";
        }
    }
    if (InGroupCheckBox.Checked)
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
            SqlDataSource1.FilterExpression += " AND [CustomerGroup]<>''";
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerGroup]<>''";
        }
    }
    if (GroupDropDownFilter.Text != "Select...")
    {
        if (!string.IsNullOrEmpty(SqlDataSource1.FilterExpression))
        {
            SqlDataSource1.FilterExpression += " AND [CustomerGroup]='{0}'";
            SqlDataSource1.FilterParameters.Add("@CustomerGroup", GroupDropDownFilter.Text);
        }
        else
        {
            SqlDataSource1.FilterExpression = "[CustomerGroup]='{0}'";
            SqlDataSource1.FilterParameters.Add("@CustomerGroup", GroupDropDownFilter.Text);
        }
    }
}

You're using the OR operator.

if(@CustomerSubscriptionType = 'Monthly' OR @CustomerStatus = 'New') will give you ALL customer's that pay monthly (Active and New) and ALL New customers (regardless of subscription type).

If you use the AND operator, you'll ONLY get New customers paying Monthly.

You'll probably want to use a combination of the two operators, so I would use the OR operator within the group and use the AND operator between groups.

if(
    (@CustomerSubscriptionType = 'Monthly' OR @CustomerSubscriptionType = 'Semi-Monthly')
AND (@CustomerStatus = 'New')
AND (@SomeOtherCriteria = 'Other' OR @SomeOtherCriteria = 'Other2')
AND etc...

To fix your code, I would use separate strings for each 'group':

SqlDataSource1.FilterExpression = string.Empty;

List<string> subscriptionTypeFilter = new List<string>();
if (MonthlyCheckBox.Checked)
{
    subscriptionTypeFilter.Add("[CustomerSubscriptionType]='Monthly'");
}

if (SemiAnnuallyCheckBox.Checked)
{
    subscriptionTypeFilter.Add("[CustomerSubscriptionType]='Semi-Annually'");
}

if (AnnuallyCheckBox.Checked)
{
subscriptionTypeFilter.Add("[CustomerSubscriptionType]='Annually'");
}

List<string> customerStatusFilter = new List<string>();
if (NewCheckBox.Checked)
{
subscriptionTypeFilter.Add("[CustomerStatus]='New'");             
}

if (ActiveCheckBox.Checked)
{
subscriptionTypeFilter.Add("[CustomerStatus]='Active'");
}

if (SuspendedCheckBox.Checked)
{
subscriptionTypeFilter.Add("[CustomerStatus]='Suspended'");
}


List<string> filters = new List<string>();

filters.Add("(" + string.Join(" OR ", subscriptionTypeFilter) + ")");
filters.Add("(" + string.Join(" OR ", customerStatusFilter) + ")");

SqlDataSource1.FilterExpression = string.Join(" AND ", filters);      

EDIT : Yeah, this is what I meant by having "to create an if for every situation and manually write each filterexpression." I was hoping I wouldn't have to do that and could make it work some other way

To do what you want dynamically, you could specify the field name and the value as custom attributes on the element:

<asp:CheckBox id="SuspendedCheckBox" runat="server" fieldName="CustomerStatus" fieldValue="Suspended" />

Once all the checkboxes have been defined properly, it's just a matter of looping through the controls.

foreach(Control c in this.Controls)
{
    if(c is CheckBox)
    {
        CheckBox cb = (CheckBox)c;

        if(cb.IsChecked)
        {
            string fieldName = cb.Attributes["fieldName"];
            string fieldValue = cb.Attributes["fieldValue"];

            someDictionaryMaybe.Add(string.Format("[{0}] = '{1}'", fieldName, fieldValue), fieldName);
        }
    }
}

// loop through the dictionary, joining the different expressions with ORs and ANDs
// or use LINQ to put it all together, it's up to you.  The fieldName was added to 
// the dictionary, which can be used to separate with ANDs and ORs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM