views:

651

answers:

4

How can I prevent the firing of multiple events of the same kind triggered by a single action?

For example, I have a ListView containing some items. When I select or deselect all items, the SelectedIndexChanged event is fired once for each item. Rather, I would like to receive a single event indication the user's action (selection/deselection of items), regardless of the number of items.

Is there any way to achieve this?

+1  A: 

Only by by coming at the problem from a slightly different direction. E.g. subscribe loss of focus.

In the end, the application or runtime cannot raise an event on "all selection changes done" without actually using something else because there is no way for the application to predict whether the user will perform another click on the control while it retains focus.

Even using focus, the user could switch back to that control.

Richard
Deselecting all items is done by a single click in the background of the ListView, but the event fires for every single deselected item nevertheless, which results in a bad performance as a calculation that should only occur once per selection/deselection get's executed for every item instead for the selection change.
Michael Barth
@Michael: why not subscribe to click events, and in the click event read the current set of selected items?
Richard
Good idea, I tried it and it works pretty good performance-wise. Only drawback is, when you click on the background of the ListView no Click event is fired, meaning I have to find another way to clear another view. Maybe I'll leave the clearing stuff in the SelectedIndexChanged event.
Michael Barth
Mhh, that's no good either, as the performance-critical method call needs to get called when the items are deselected, too, so I cannot call it in the click event handler.
Michael Barth
A: 

If your ListView is in virtual mode, you could use the VirtualItemsSelectionRangeChanged event. This event will be fired only once for the user's action (selection/deseclection).

EFrank
What does the virtual mode entail? Never really heard of this. On MSDN it states "In order to use virtual mode, you must handle the RetrieveVirtualItem event (...)". Do I have to provide other functionality for a virtual ListView to work like the non-virtual ListViews I am used to?
Michael Barth
"Virtual mode" means that the ListViewItems are not created at once for all items, but rather on demand, only for the items that are currently visible. The virtual mode is especially useful if you have large amounts of data that should be displayed, and if you store the data somewhere else in you application besides the ListView.So basically the two differences are to store the data for the items on your own, and to handle the RetrieveVirtualItem event.
EFrank
+3  A: 

You can't change the ListView code, and subclassing it doesn't provide many options.

I would suggest that you simply add a small delay (200ms or similar) to your code - i.e. you only do the calculation a little while after the last update. Something like:

using System;
using System.Windows.Forms;
static class Program {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        ListView list;
        TextBox txt;
        Timer tmr = new Timer();
        tmr.Interval = 200;
        Form form = new Form {
            Controls = {
                (txt = new TextBox { Dock = DockStyle.Fill, Multiline = true}),
                (list = new ListView { Dock = DockStyle.Right, View = View.List,
                   Items = { "abc", "def" , "ghi", "jkl", "mno" , "pqr"}})
            }
        };
        list.SelectedIndexChanged += delegate {
            tmr.Stop();
            tmr.Start();
        };
        tmr.Tick += delegate {
            tmr.Stop();
            txt.Text += "do work on " + list.SelectedItems.Count + " items"
                 + Environment.NewLine;
        };
        Application.Run(form);
    }
}
Marc Gravell
An example would be very much appreciated :)
Michael Barth
I see, but this approach does not prevent the execution but postpones it. What I am looking for is to execute once and drop all further unnecessary executions. As soon as something get's selected or deselected, I am updating a variable that holds the overall state of the selection which needs to be done exactly once per user action.
Michael Barth
You have to drop the **earlier** actions - otherwise you don't know that your acting on the right data. The code as shown drops everything except for the last one. As such, it indeed executes only once per user action.
Marc Gravell
Oh wow, now I get it. Great, thanks!
Michael Barth
A: 

i had a same type of problem n did't found a solution yet...plz help...i'm a new bee in c#.net.this is my code........

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Registration.aspx.cs" Inherits="_Default" %>

<%@ Register assembly="DevExpress.Web.ASPxEditors.v9.2, Version=9.2.9.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" namespace="DevExpress.Web.ASPxEditors" tagprefix="dxe" %>

Registration Page .style1 { width: 100%; height: 501px; } .style2 { width: 112px; } .style3 { width: 112px; height: 8px; } .style4 { height: 8px; } .style9 { width: 112px; height: 3px; } .style10 { height: 3px; } .style11 { width: 112px; height: 2px; } .style12 { height: 2px; } .style13 { width: 112px; height: 5px; } .style14 { height: 5px; } .style15 { width: 112px; height: 1px; } .style16 { height: 1px; } .style17 { width: 112px; height: 9px; } .style18 { height: 9px; } .style19 { width: 112px; height: 16px; } .style20 { height: 16px; } .style21 { width: 112px; height: 10px; } .style22 { height: 10px; } &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp  

    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<asp:Menu 
        ID="Menu1" runat="server" BackColor="#B5C7DE" DynamicHorizontalOffset="2" 
        Font-Names="Verdana" Font-Size="Small" ForeColor="#284E98" 
        onmenuitemclick="Menu1_MenuItemClick" Orientation="Horizontal" 
        StaticSubMenuIndent="10px">
        <StaticSelectedStyle BackColor="#507CD1" />
        <StaticMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px" />
        <DynamicHoverStyle BackColor="#284E98" ForeColor="White" />
        <DynamicMenuStyle BackColor="#B5C7DE" />
        <DynamicSelectedStyle BackColor="#507CD1" />
        <DynamicMenuItemStyle HorizontalPadding="5px" VerticalPadding="2px" />
        <StaticHoverStyle BackColor="#284E98" ForeColor="White" />
        <Items>
            <asp:MenuItem Text="Quiz Select" Value="Quiz Select"></asp:MenuItem>
            <asp:MenuItem Text="Log Out" Value="Log Out"></asp:MenuItem>
        </Items>
    </asp:Menu>
    &nbsp;&nbsp;

    <table class="style1" width="70%">
        <tr>
            <td class="style9">
                <asp:Label ID="lblName" runat="server" Text="Name"></asp:Label>
            </td>
            <td class="style10">
                <asp:TextBox ID="txtName" runat="server" Width="200px"></asp:TextBox>
                <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" 
                    ControlToValidate="txtName" ErrorMessage="*" ValidationGroup="A"></asp:RequiredFieldValidator>
            </td>
        </tr>
        <tr>
            <td class="style11">
                <asp:Label ID="lblEmail" runat="server" Text="Email"></asp:Label>
            </td>
            <td class="style12">
                <asp:TextBox ID="txtEmail" runat="server" Width="200px" 
                    ontextchanged="Button1_Click"></asp:TextBox>
                <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" 
                    ControlToValidate="txtEmail" ErrorMessage="*" 
                    ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" 
                    ValidationGroup="A"></asp:RegularExpressionValidator>
                <asp:Label ID="lblEmailNM" runat="server"></asp:Label>
            </td>
        </tr>
        <tr>
            <td class="style13">
                <asp:Label ID="lblPassword" runat="server" Text="Password"></asp:Label>
            </td>
            <td class="style14">
                <asp:TextBox ID="txtPassword" runat="server" TextMode="Password" Width="200px"></asp:TextBox>
                <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" 
                    ControlToValidate="txtPassword" ErrorMessage="*" ValidationGroup="A"></asp:RequiredFieldValidator>
            </td>
        </tr>
        <tr>
            <td class="style15">
                <asp:Label ID="lblConfirmPassword" runat="server" Text="Confirm Password"></asp:Label>
            </td>
            <td class="style16">
                <asp:TextBox ID="txtConfirmPassword" runat="server" TextMode="Password" 
                    Width="200px"></asp:TextBox>
                <asp:CompareValidator ID="CompareValidator1" runat="server" 
                    ControlToCompare="txtPassword" ControlToValidate="txtConfirmPassword" 
                    ErrorMessage="*" ValidationGroup="A"></asp:CompareValidator>
            </td>
        </tr>
        <tr>
            <td class="style17">
                <asp:Label ID="lblGender" runat="server" Text="Gender"></asp:Label>
            </td>
            <td class="style18">
                <asp:RadioButtonList ID="rbGender" runat="server" RepeatDirection="Horizontal">
                    <asp:ListItem>Male</asp:ListItem> 
                    <asp:ListItem>Female</asp:ListItem>
                </asp:RadioButtonList>
            </td>
        </tr>
        <tr>
            <td class="style17">
                <asp:Label ID="lblDOB" runat="server" Text="DOB"></asp:Label>
            </td>
            <td class="style18">
                <dxe:ASPxDateEdit ID="ASPxDateEdit1" runat="server">
                </dxe:ASPxDateEdit>
            </td>
        </tr>
        <tr>
            <td class="style19">
                <asp:Label ID="lblAddress1" runat="server" Text="Address1"></asp:Label>
            </td>
            <td class="style20">
                <asp:TextBox ID="txtAddress1" runat="server" TextMode="MultiLine" Width="200px" 
                    Height="20px"></asp:TextBox>
                <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" 
                    ControlToValidate="txtAddress1" ErrorMessage="*" ValidationGroup="A"></asp:RequiredFieldValidator>
            </td>
        </tr>
        <tr>
            <td class="style3">
                <asp:Label ID="lblAddress2" runat="server" Text="Address2"></asp:Label>
            </td>
            <td class="style4">
                <asp:TextBox ID="txtAddress2" runat="server" TextMode="MultiLine" Width="200px" 
                    Height="20px"></asp:TextBox>
            </td>
        </tr>
        <tr>
            <td class="style21">
                <asp:Label ID="lblCountry" runat="server" Text="Country"></asp:Label>
            </td>
            <td class="style22">
                <asp:DropDownList ID="ddlCountry" runat="server" Height="20px" Width="200px" 
                    onselectedindexchanged="ddlCountry_SelectedIndexChanged">
                    <asp:ListItem>India</asp:ListItem>
                    <asp:ListItem>USA</asp:ListItem>
                    <asp:ListItem>China</asp:ListItem>
                    <asp:ListItem>France</asp:ListItem>
                    <asp:ListItem>German</asp:ListItem>
                    <asp:ListItem>Japan</asp:ListItem>
                </asp:DropDownList>
                <asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" 
                    ControlToValidate="ddlCountry" ErrorMessage="*" ValidationGroup="A"></asp:RequiredFieldValidator>
            </td>
        </tr>
        <tr>
            <td class="style9">
                <asp:Label ID="lblState" runat="server" Text="State"></asp:Label>
            </td>
            <td class="style10">
                <asp:DropDownList ID="ddlState" runat="server" Height="20px" Width="200px">
                    <asp:ListItem>Delhi</asp:ListItem>
                    <asp:ListItem>Punjab</asp:ListItem>
                    <asp:ListItem>UP</asp:ListItem>
                    <asp:ListItem>Haryana</asp:ListItem>
                    <asp:ListItem>New York</asp:ListItem>
                    <asp:ListItem>Paris</asp:ListItem>
                    <asp:ListItem>Tokyo</asp:ListItem>
                    <asp:ListItem>Bejing</asp:ListItem>
                </asp:DropDownList>
                <asp:RequiredFieldValidator ID="RequiredFieldValidator5" runat="server" 
                    ControlToValidate="ddlState" ErrorMessage="*" ValidationGroup="A"></asp:RequiredFieldValidator>
            </td>
        </tr>
        <tr>
            <td class="style17">
                <asp:Label ID="lblCity" runat="server" Text="City"></asp:Label>
            </td>
            <td class="style18">
                <asp:DropDownList ID="ddlCity" runat="server" Height="20px" Width="200px">
                    <asp:ListItem>New delhi</asp:ListItem>
                    <asp:ListItem>Amritsar</asp:ListItem>
                    <asp:ListItem>Gurgaon</asp:ListItem>
                    <asp:ListItem>Noida</asp:ListItem>
                    <asp:ListItem>Chandigarh</asp:ListItem>
                    <asp:ListItem>New York</asp:ListItem>
                    <asp:ListItem>Paris</asp:ListItem>
                </asp:DropDownList>
            </td>
        </tr>
        <tr>
            <td class="style2">
                </td>
            <td>
                <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Save" 
                    Width="100px" ValidationGroup="A" />
                <asp:Label ID="lblRegister" runat="server" Font-Bold="True" Font-Italic="True" 
                    ForeColor="#999966"></asp:Label><asp:LinkButton ID="lnkLogin" 
                    runat="server" onclick="lnkLogin_Click">Back to Login</asp:LinkButton>
                <asp:HiddenField ID="HiddenField1" runat="server" />

            </td>
        </tr>
        </table>

</div>
</form>

rajiv