Click here to Skip to main content
15,892,768 members
Articles / Desktop Programming / WPF

Displaying User Friendly Enum Values in WPF

Rate me:
Please Sign up or sign in to vote.
4.94/5 (25 votes)
12 Mar 2014CPOL13 min read 105.7K   1.7K   68  
Presents a helper class to easily display user-friendly enum value representations including customizable and localizable text, images, and arbitrary XAML content. This class can also be used as a general XAML switch statement for enum and non-enum classes.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Collections.ObjectModel;
using System.Windows;
using System.Collections;
using System.Collections.Specialized;
using System.Windows.Data;

namespace EnumBindings
{
    public class TableGridCell : Border
    {
        public TableGridCell()
        {

        }

        public TableGridCell(UIElement content)
        {
            this.Child = content;
        }
    }

    [ContentProperty("Children")]
    public class TableGridRow : RowDefinition
    {
        private TableRowElementCollection m_children;

        class TableRowElementCollection : Collection<UIElement>
        {
            public TableRowElementCollection (TableGridRow row)
	        {
                TableRow = row;
	        }

            public TableGridRow TableRow { get; private set; }
            
            protected override void ClearItems()
            {
                for (int i = Count-1; i >= 0; i--)
                {
                    TableRow.OnRemoveChild(i, this[i]);
                }
                base.ClearItems();
            }

            protected override void InsertItem(int colIndex, UIElement child)
            {
                TableRow.OnAddElement(colIndex, child);
                base.InsertItem(colIndex, child);
            }

            protected override void RemoveItem(int index)
            {
                TableRow.OnRemoveChild(index, this[index]);
                base.RemoveItem(index);
            }

            protected override void SetItem(int index, UIElement item)
            {
                int oldCount = TableRow.Table.Children.Count;
                TableRow.OnRemoveChild(index, this[index]);
                TableRow.OnAddElement(index, item);
                base.SetItem(index, item);
            }
        }

        private List<TableGridCell> m_cells;

        public TableGridRow()
        {
            m_cells = new List<TableGridCell>();
            m_children = new TableRowElementCollection(this);   
        }

        

        private void OnRemoveChild(int colIndex, UIElement child)
        {
            TableGridCell cell = m_cells[colIndex];
            m_cells.RemoveAt(colIndex);
            if (Table != null)
            {
                Table.Children.Remove(cell);
            }
            for (int i = colIndex; i < m_cells.Count; i++)
            {
                cell = m_cells[i];
                cell.SetValue(Grid.ColumnProperty, i);
            }
        }

        private int GetStartingGridColumFor(int colIndex)
        {
            if (colIndex == 0) return 0;
            TableGridCell previousCell = m_cells[colIndex-1];
            return (int)previousCell.GetValue(Grid.ColumnProperty) + (int)previousCell.GetValue(Grid.ColumnSpanProperty);
        }

        private void OnAddElement(int colIndex, UIElement child)
        {
            TableGridCell cell = child as TableGridCell;
            if (cell == null)
            {
                cell = new TableGridCell(child);
            }
            m_cells.Insert(colIndex, cell);
            int gridColIndex = GetStartingGridColumFor(colIndex);
            cell.SetValue(Grid.ColumnProperty, gridColIndex);

            for (int i = colIndex + 1; i < m_cells.Count; i++)
            {
                cell = m_cells[i];
                cell.SetValue(Grid.ColumnProperty, GetStartingGridColumFor(i));
            }

            if (Table != null)
            {
                cell.SetValue(Grid.RowProperty, RowIndex);    
                BindingOperations.SetBinding(cell, FrameworkElement.StyleProperty, new Binding() { Source = Table, Path = new PropertyPath("CellStyle") });

                AdjustNumberOfTableColumns();
                
                //Table.Children.Add(cell);
                Table.AddInternalChild(cell);
                
            }
            
        }

        private void AdjustNumberOfTableColumns()
        {
            int lastGridColIndex = GetStartingGridColumFor(m_cells.Count);
            while (Table.ColumnDefinitions.Count < lastGridColIndex)
            {
                Table.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Auto) });
            }
        }

        public IList Children { get { return m_children; } }

        private TableGrid m_table;

        public TableGrid Table
        {
            get { return m_table; }
            set {


                if (value != null)
                {
                    m_table = value;
                    int colIndex = 0;
                    foreach (TableGridCell cell in m_cells)
                    {
                        BindingOperations.SetBinding(cell, FrameworkElement.StyleProperty, new Binding() { Source = Table, Path = new PropertyPath("CellStyle") });

                        AdjustNumberOfTableColumns();

                        //Table.Children.Add(cell);
                        Table.RemoveInternalChild(cell);
                        colIndex++;
                    }
                }
                else
                {
                    foreach (TableGridCell cell in m_cells)
                    {
                        BindingOperations.ClearBinding(cell, FrameworkElement.StyleProperty);
                        // Table.Children.Remove(cell);
                        Table.RemoveInternalChild(cell);
                    }
                    m_table = value;
                }
            }
        }

        private int m_rowIndex;

        public int RowIndex { 
            get { return m_rowIndex; }
            set
            {
                m_rowIndex = value;
                foreach (TableGridCell cell in m_cells)
                {
                    cell.SetValue(Grid.RowProperty, m_rowIndex);
                }
                
            }
        }
    }

    [ContentProperty("Children")]
    public class TableRow : FrameworkElement
    {
        private TableRowElementCollection m_children;

        class TableRowElementCollection : Collection<UIElement>
        {
            public TableRowElementCollection (TableRow row)
	        {
                TableRow = row;
	        }

            public TableRow TableRow { get; private set; }
            
            protected override void ClearItems()
            {
                for (int i = Count-1; i >= 0; i--)
                {
                    TableRow.OnRemoveChild(i, this[i]);
                }
                base.ClearItems();
            }

            protected override void InsertItem(int colIndex, UIElement child)
            {
                TableRow.OnAddElement(colIndex, child);
                base.InsertItem(colIndex, child);
            }

            protected override void RemoveItem(int index)
            {
                TableRow.OnRemoveChild(index, this[index]);
                base.RemoveItem(index);
            }

            protected override void SetItem(int index, UIElement item)
            {
                int oldCount = TableRow.Table.Children.Count;
                TableRow.OnRemoveChild(index, this[index]);
                TableRow.OnAddElement(index, item);
                base.SetItem(index, item);
            }
        }

        private List<TableGridCell> m_cells;

        public TableRow()
        {
            m_cells = new List<TableGridCell>();
            m_children = new TableRowElementCollection(this);   
        }

        

        private void OnRemoveChild(int colIndex, UIElement child)
        {
            TableGridCell cell = m_cells[colIndex];
            m_cells.RemoveAt(colIndex);
            RemoveLogicalChild(cell);
            if (Table != null)
            {
                Table.Children.Remove(cell);
            }
            for (int i = colIndex; i < m_cells.Count; i++)
            {
                cell = m_cells[i];
                cell.SetValue(Grid.ColumnProperty, i);
            }
        }

        private int GetStartingGridColumFor(int colIndex)
        {
            if (colIndex == 0) return 0;
            TableGridCell previousCell = m_cells[colIndex-1];
            return (int)previousCell.GetValue(Grid.ColumnProperty) + (int)previousCell.GetValue(Grid.ColumnSpanProperty);
        }

        private void OnAddElement(int colIndex, UIElement child)
        {
            TableGridCell cell = child as TableGridCell;
            if (cell == null)
            {
                cell = new TableGridCell(child);
            }
            m_cells.Insert(colIndex, cell);
            int gridColIndex = GetStartingGridColumFor(colIndex);
            cell.SetValue(Grid.ColumnProperty, gridColIndex);

            for (int i = colIndex + 1; i < m_cells.Count; i++)
            {
                cell = m_cells[i];
                cell.SetValue(Grid.ColumnProperty, GetStartingGridColumFor(i));
            }

            if (Table != null)
            {
                cell.SetValue(Grid.RowProperty, RowIndex);    
                BindingOperations.SetBinding(cell, FrameworkElement.StyleProperty, new Binding() { Source = Table, Path = new PropertyPath("CellStyle") });

                AdjustNumberOfTableColumns();
                
                //Table.Children.Add(cell);
                Table.AddInternalChild(cell);
                
            }
            AddLogicalChild(cell);
        }

        private void AdjustNumberOfTableColumns()
        {
            int lastGridColIndex = GetStartingGridColumFor(m_cells.Count);
            while (Table.ColumnDefinitions.Count < lastGridColIndex)
            {
                Table.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Auto) });
            }
        }

        public IList Children { get { return m_children; } }

        private TableGrid m_table;

        public TableGrid Table
        {
            get { return m_table; }
            set {


                if (value != null)
                {
                    m_table = value;
                    int colIndex = 0;
                    foreach (TableGridCell cell in m_cells)
                    {
                        BindingOperations.SetBinding(cell, FrameworkElement.StyleProperty, new Binding() { Source = Table, Path = new PropertyPath("CellStyle") });

                        AdjustNumberOfTableColumns();

                        //Table.Children.Add(cell);
                        RemoveLogicalChild(cell);
                        Table.AddInternalChild(cell);
                        AddLogicalChild(cell);
                        colIndex++;
                    }
                }
                else
                {
                    foreach (TableGridCell cell in m_cells)
                    {
                        BindingOperations.ClearBinding(cell, FrameworkElement.StyleProperty);
                        // Table.Children.Remove(cell);
                        Table.RemoveInternalChild(cell);
                    }
                    m_table = value;
                }
            }
        }

        private int m_rowIndex;

        public int RowIndex { 
            get { return m_rowIndex; }
            set
            {
                m_rowIndex = value;
                foreach (TableGridCell cell in m_cells)
                {
                    cell.SetValue(Grid.RowProperty, m_rowIndex);
                }
                
            }
        }

        public int ColumnWidth
        {
            get 
            {
                return GetStartingGridColumFor(m_cells.Count);
            }
        }
    }

    [ContentProperty("TableRows")]
    [StyleTypedProperty(Property="CellStyle", StyleTargetType=typeof(TableGridCell))]
    public class TableGrid : Grid
    {
        private class TableRowsCollection : Collection<TableRow>
        {
            public TableRowsCollection(TableGrid table)
            {
                Table = table;
            }

            public TableGrid Table { get; private set; }

            protected override void InsertItem(int index, TableRow item)
            {
                Table.InsertTableRow(index, item);
                base.InsertItem(index, item);
            }

            protected override void RemoveItem(int index)
            {
                Table.RemoveTableRow(index);
                base.RemoveItem(index);
            }

            protected override void SetItem(int index, TableRow item)
            {
                Table.RemoveTableRow(index);
                Table.InsertTableRow(index, item);
                base.SetItem(index, item);
            }

            protected override void ClearItems()
            {
                for (int i = Count-1; i >= 0; i--)
                {
                    Table.RemoveTableRow(i);

                }
                base.ClearItems();
            }
        }

        public TableGrid()
        {
            
            
            m_tableRows = new TableRowsCollection(this);
            HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            VerticalAlignment = System.Windows.VerticalAlignment.Top;
        }

        public Style CellStyle
        {
            get { return (Style)GetValue(CellStyleProperty); }
            set { SetValue(CellStyleProperty, value); }
        }

        // Using a DependencyProperty as t  he backing store for CellStyle.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CellStyleProperty =
            DependencyProperty.Register("CellStyle", typeof(Style), typeof(TableGrid), new UIPropertyMetadata(null));

        private TableRowsCollection m_tableRows;

        public IList TableRows
        {
            get { return m_tableRows; }
            
        }

        
        private void RemoveTableRow(int rowIndex)
        {
            TableRow row = m_tableRows[rowIndex];
            row.Table = null;
            RemoveLogicalChild(row);
            InternalChildren.Remove(row);
            // Adjust row index for all items below.
            for (int i = rowIndex; i < m_tableRows.Count; i++)
            {
                m_tableRows[i].RowIndex = i;
            }
        }

        internal void AddInternalChild(UIElement child)
        {
            InternalChildren.Add(child);
            RemoveLogicalChild(child);
        }

        internal void RemoveInternalChild(UIElement child)
        {
            InternalChildren.Remove(child);
        }

        private void InsertTableRow(int rowIndex, Object element)
        {
            
            if (element == null) throw new ArgumentNullException();
            
            TableRow row = element as TableRow;
            if (row == null)
            {
                UIElement uielement = element as UIElement;
                if (uielement == null) throw new ArgumentException("Element added to TableGrid must be a TableGridRow or a UIElement");
                row = new TableRow();
                row.Children.Add(uielement);
            }

            InternalChildren.Add(row);
            row.Table = this;
            row.RowIndex = rowIndex;
            
            // Adjust row index for all items below.
            for (int i = rowIndex+1; i < m_tableRows.Count; i++)
            {
                
                m_tableRows[i].RowIndex = i;
            }

            // Ensure that number of rowdefinitions are sufficient
            while (RowDefinitions.Count < m_tableRows.Count)
            {
                RowDefinitions.Add(new RowDefinition()); 
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Sweden Sweden
Henrik Jonsson is a Microsoft Professional Certified Windows Developer (MCPD) that currently works as an IT consultant in Västerås, Sweden.

Henrik has worked in several small and large software development projects in various roles such as architect, developer, CM and tester.

He regularly reads The Code Project articles to keep updated about .NET development and get new ideas. He has contributed with articles presenting some useful libraries for Undo/Redo, Dynamic Linq Sorting and a Silverlight 5 MultiBinding solution.

Comments and Discussions