DCSIMG
Aggregate CheckBox for DataGridCheckBoxColumn (Part 2) - David Sackstein's Blog

Aggregate CheckBox for DataGridCheckBoxColumn (Part 2)

In the previous post I described the requirement to create an aggregate CheckBox for a DataGridCheckBoxColumn.

You can download the source code for my solution here.

In this post I describe the high level design of my solution as documentation for the source code. If you are looking for the WPF techniques themselves, you can skip to the next post (Part 3).

Setting the Scene

The project contains three assemblies:

  1. PresentationLayer: This is a WPF window application.
  2. UserControls: A class library that hosts the EmployeeListControl.
  3. BusinessLayer: A class library that hosts the Employee class.

BusinessLayer

The only class in this library is the Employee class. As you can see I preferred the INotifyPropertyChanged approach over Dependency Properties as this is a business object.

    public class Employee : INotifyPropertyChanged

    {

        private bool isManager;

        public bool IsManager

        {

            get { return isManager; }

            set {

                isManager = value;

                RaisePropertyChanged("IsManager");

            }

        }

 

        private string name;

        public string Name

        {

            get { return name; }

            set {

                name = value;

                RaisePropertyChanged("Name");

            }

        }

 

        #region INotifyPropertyChanged Members

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        #endregion

 

        void RaisePropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        }

    }

UserControls

I am going to place all the UI elements required for displaying a collection of Employees in a UserControl called EmployeeListControl. The interface between the PresentationLayer and the UserControl will be expressed in terms of business objects. “Here is a collection of Employees, present them to the user and allow him to edit the collection and the Employees”.

This is one of the nice side-effects of databinding. One module can concentrate on the data, the other on the UI and databinding synchronizes them behind the scenes.

It’s often best to appreciate the interface of a module (in this case, the EmployeeListControl) from the outside, by seeing how its used. The interface of the module seen this way is a requirements document.

So, let’s take a quick look at the PresentationLayer and then drill down into the EmployeeListControl.

PresentationLayer

This assembly contains one window (MainWindow) that hosts two buttons and an EmployeeListControl. This is the XAML for the MainWindow:

<Window x:Class="PresentationLayer.MainWindow"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:uc="clr-namespace:UserControls;assembly=UserControls"

       Width="200"

       Height="300"

       ResizeMode="NoResize"

       Loaded="Window_Loaded">

    <StackPanel>

        <Grid>

            <Grid.ColumnDefinitions>

                <ColumnDefinition/>

                <ColumnDefinition/>

            </Grid.ColumnDefinitions>

            <Button Grid.Column="0" Click="btnFill_Click">Fill</Button>

            <Button Grid.Column="1" Click="btnCheck_Click">Check All</Button>

        </Grid>

        <uc:EmployeeListControl x:Name="ctlEmployeeList"/>

    </StackPanel>

</Window>

And this is the code behind:

    public partial class MainWindow : Window

    {

        // Use of ObservableCollection allows bound controls to react to changes to the collection

 

        ObservableCollection<Employee> employees;

 

        public MainWindow()

        {

            InitializeComponent();

        }

 

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            employees = new ObservableCollection<Employee>();

            ctlEmployeeList.Employees = employees;

        }

 

        private void btnFill_Click(object sender, RoutedEventArgs e)

        {

            Button btn = sender as Button;

 

            // Shows that ObservableCollection allows bound controls to react to changes to the collection

 

            if (btn.Content.ToString() == "Fill")

            {

                employees.Add(new Employee { IsManager = true, Name = "Bill" });

                employees.Add(new Employee { IsManager = true, Name = "Tom" });

                employees.Add(new Employee { IsManager = false, Name = "***" });

                employees.Add(new Employee { IsManager = true, Name = "Harry" });

                employees.Add(new Employee { IsManager = false, Name = "Alice" });

 

                btn.Content = "Empty";

            }

            else

            {

                employees.Clear();

                btn.Content = "Fill";

            }

        }

 

        private void btnCheck_Click(object sender, RoutedEventArgs e)

        {

            Button btn = sender as Button;

 

            // Demonstrate that INotifyPropertyChanged on Employee allows bound controls

            // to react to changes to its properties

 

            if (btn.Content.ToString() == "Check All")

            {

                foreach (Employee employee in employees)

                {

                    employee.IsManager = true;

                }

                btn.Content = "Uncheck All";

            }

            else

            {

                foreach (Employee employee in employees)

                {

                    employee.IsManager = false;

                }

                btn.Content = "Check All";

            }

        }

    }

As you can see, (in the Window_Loaded handler) the only interface with the EmployeeListControl is the Employees property which exposes an ObservableCollection<Employee>.

The affect of the “Fill” button on the number of entries in the EmployeeListControl is implemented solely by adding or removing items for the collection.

Similarly, the affect of the “Check All” button on the entries in the rows of the EmployeeListControl is implemented solely by setting properties of Employee objects in the collection.

OK. I think that sets the scene. In the next post we will take a detailed look at the EmployeeListControl which implements an aggregate CheckBox in a Column Header which allows you to check / uncheck the IsManager property for all employees in the collection.

Published Friday, April 17, 2009 11:55 PM by David Sackstein
תגים:, ,

Comments

# Aggregate CheckBox for DataGridCheckBoxColumn (Part 3)

Saturday, April 18, 2009 4:10 AM by David's Blog

I described the problem at hand in the first post in this series. In the previous post I described the

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems