Friday, April 19, 2013

TreeView DataGrid with collapsible lines.

Datagrid is the easiest way to display data in tables, but sometimes a simple datagrid is not enough. Sometimes we need to group certain types of data with properties in common, something like a treeview. Imagine you have a system where the user register multiple employees, and some of these employees are managers and these managers have subordinates. The user of the system may require the datagrid view only users who are not managers, or vice versa. For this you need to create something like a TreevireeDataGrid, or a datagrid in three or more dimensions (a tradicional datagrid has only two dimensions, row and column).
In order to create this desired TreeviewDatagrid we divide this task into three parts. In this first post we will show you how to hide rows in a DataGrid, you'll see that this is a fundamental part in the process.
In the second post will show how to edit the header of the datagrid to add pictures to it (like a button) to collapse or show the items that belong to him.No terceiro post vamos tratar da lógica de fazer um TreeviewDatagrid e juntar o conhecimento de todos os posts anteriores.
Initially we will create an Employee class that represents a employee, each employee will have two property: Name and IsGerent.

    public class Employee
    {
        public string Name { get; set; }

        public bool IsGerent { get; set; }

        public Employee(string name, bool isGerent)
        {
            Name = name;
            IsGerent = isGerent;
            Visibility = Visibility.Visible;
        }
    }

To collapse a datagrid row we should edit the datagrid’s RowStyle and bind it’s Visibility property to the datagrid Model property that will control it´s visibility, as shown below:

            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="Visibility" Value="{Binding Path=RowVisibility, UpdateSourceTrigger=PropertyChanged}" />               
                </Style>
            </DataGrid.RowStyle>
So, whenever the Model´s property RowVisibility is of type Collapsed, that datagrid row will be collapsed.
To get the desired effect we created a model for each row of the datagrid, containing the properties: Name, IsGerent and RowVisibility. Them we bound the first column of datagrid with the Name property of the model and the second column with the IsGerent property. As shown below:

    public class CollapsedDataGridRowModel : INotifyPropertyChanged
    {
        public string Name { get; set; }

        public bool IsGerent { get; set; }

        private Visibility _rowVisibility;

        public Visibility RowVisibility
        {
            get { return _rowVisibility; }
            set
            {
                _rowVisibility = value;
                OnPropertyChanged("RowVisibility");
            }
        }

        public CollapsedDataGridRowModel(Employee employee)
        {
            Name = employee.Name;

            IsGerent = employee.IsGerent;

            RowVisibility = Visibility.Visible;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        // Create the OnPropertyChanged method to raise the event
        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }
 Our datagrid has a list of employees, so a model was created for the datagrid itself containing the list of Employees.
    public class ColapsedDataGridModel
    {
        private List<CollapsedDataGridRowModel> _employees;

        public List<CollapsedDataGridRowModel> Employees
        {
            get { return _employees; }
            set
            {
                _employees = value;
                OnPropertyChanged("Employees");
            }
        }

        public ColapsedDataGridModel(List<Employee> employees)
        {
            foreach (var employee in employees)
            {
                if (Employees == null) Employees = new List<CollapsedDataGridRowModel>();
                Employees.Add(new CollapsedDataGridRowModel(employee));
            }
        }
       
    }
 Note that it is fundamental that CollapsedDataGridRowModel implements the INotifyPropertyChanged interface, since a change in RowVisibility will change the state of the datagrid.
Note on Class Visibility: The visibility of an object can be of three types:
1 – Visible: The object is visible and is part of the windows layout;
2 – Hidden: The object is not visible and is part of the window layout;
3 – Collapsed: The object is not visible and it is not part of the window layout. It is equivalent to the object has dimensions equal to zero.
The desired effect is showed inthe figure below:
By clicking the Hide Managers button will collapse the datagrid rows where the Manager check box is checked. For this to happen you need a small method that checks which are employees who are managers and change the Visibility property line, as follows:

        private void ColapseGerents(object sender, RoutedEventArgs e)
        {
            foreach (var employee in Model.Employees)
            {
                if (employee.IsGerent)
                {
                    employee.RowVisibility = Visibility.Collapsed;
                }
            }

            OnPropertyChanged("Model");
        }
The same thing is done for the Hide Managers button. The result, after a click in the “Hide Manager” button is:
If you want more details about the code, you can download the project example shown in the link below:
 That's it guys, I hope this has been helpful! If you have questions, compliments or questions just leave a comment!
See you in the next post where we will insert buttons on the Header of the datagrid line to collapse the rows, that is somehow, part of the top line. We can expand the example of the employee making the employees managers have subordinates that are shown only when the user expands the line manager.
Thanks for reading!!
Obrigado por lerem!!
TapiocaCom Team!

No comments:

Post a Comment