Jaa


How many items are there in a WPF ListBox?

I received a question through my blog. The question was about “a GroupBox which lists some errors. The count of these Errors(ListItems) vary. How can I count the no. of Rows in GroupBox?”

Technically, a GroupBox contains only 1 item defined by its content but that’s not a useful answer! Often the content of a GroupBox is something like a StackPanelor a Grid control where you can have multiple items. It is also common want to add a Header and Border to the GroupBox so these are built-in to the GroupBox control.

Besides, it’s clear that the person asking the question knows that there is only one content item in a GroupBox since they mention having ListItem elements for error messages. So, my guess is that they have a List control as the GroupBox ‘s content. I’ve never seen this control used but I am quite familiar with ListBox and ListView controls.

The way I would approach this problem is to data bind the ListBox or ListView control to an ObservableCollection. The error messages are added to the ObservableCollection which has a Count property. Since we’re talking about simple string, we can do things very straightforwardly. With other object types, you would also need DataTemplate and CollectionViewSource resources.

To access the ObservableCollection definition, I added this to the using statements at the top of the C# file:

using System.Collections.ObjectModel;

 

Now, let’s define the collection:

    /// <summary>

    /// Defines an observable collection of strings

    /// </summary>

    public class ErrorMessageCollection : ObservableCollection<String>

    {

        private static ObservableCollection<String> errorMessages;

        /// <summary>

        /// The XAML needs a parameterless constructor

        /// </summary>

        public ErrorMessageCollection()

        {

            // All the constructor does is instantiate an observable collection of strings

            errorMessages = new ObservableCollection<string>();

        }

        /// <summary>

        /// Returns the collection of strings

        /// </summary>

        public ObservableCollection<String> ErrorMessages

        {

            get { return errorMessages; }

        }

        /// <summary>

        /// Adds a new error message to the collection

        /// </summary>

        /// <param name="errorMessage"></param>

        public static void AddMessage(string errorMessage)

        {

            errorMessages.Add(errorMessage);

        }

        /// <summary>

        /// gets the number of error messages in the collection

        /// </summary>

        public static int ErrorMessageCount

        {

            get { return errorMessages.Count; }

        }

    }

 

You need to add a namespace definition to the XAML to access your application’s namespace. In my example, I defined:

   xmlns:local="clr-namespace:GroupBoxExample"

 

You also need to define a static resource which allows the XAML to access the ObservableCollection. For example:

    <Window.Resources>

        <local:ErrorMessageCollection x:Key="Errors" />

    </Window.Resources>

Then you can define the ListBox or ListView control in the GroupBox control. For example:

        <GroupBox Grid.Row="0" Name="ErrorMessageGroupBox" Header="Error Messages" BorderThickness="3" >

                <!--

                    This ListBox is bound to the Errors defined above. The Errors resource accesses

                    the ErrorMessageCollection defined in the application's code. In particular, the

                    ListBox is bound to the ErrorMessages property of the ErrorMessageCollection

                -->

                <ListBox Name="ErrorMessageListBox" ItemsSource="{Binding Source={StaticResource Errors}, Path=ErrorMessages}" />

        </GroupBox>

In the application code, I set up a loop which adds a random number of error messages with the total being between 100 and 1000 messages.

To demonstrate the Count property of the ObservableCollection, I added a button which will display a containing the number of error messages using the ErrorMessageCollection‘s ErrorMessageCount property.

I have uploaded the full example as a zip file.

 

GroupBoxExample.zip

Comments