Click here to Skip to main content
15,896,269 members
Articles / Desktop Programming / WPF

WPF PropertyGrid - MVVM techniques

Rate me:
Please Sign up or sign in to vote.
4.86/5 (11 votes)
11 Mar 2010CPOL5 min read 63.3K   1.8K   34  
How to build a multicolumn ListView that selects cell templates based on the row data type; and how to create a ViewModel on the fly for each cell template.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows.Data;
using System.Windows;
using System.Reflection;

namespace PropertyGridDemo
{
    // This is the wrapper (ViewModel) that we use to edit a ColorItem.  It exposes
    // the RGB components as a Color struct, for the purposes of binding to the controls.
    public class ColorItemViewModel : FrameworkElement
    {
        public static readonly DependencyProperty ItemProperty =
            DependencyProperty.Register("Item", typeof(ColorItem), typeof(ColorItemViewModel));

        // The original data source.  This is a dependency property because
        // we set a binding on it in the xaml.
        public ColorItem Item
        {
            get
            {
                return (ColorItem)GetValue(ItemProperty);
            }
            set
            {
                SetValue(ItemProperty, value);
            }
        }

        // Transform the RGB properties of the original item into a Color struct and back.
        public ColorSelection Color
        {
            get
            {
                if (Item == null)
                    return null;
                Color itemColor = System.Windows.Media.Color.FromScRgb(1.0f, Item.Red, Item.Green, Item.Blue);
                foreach (var ac in availableColors)
                    if (ac.Color == itemColor)
                        return ac;
                return null;
            }
            set
            {
                if (Item != null)
                {
                    Item.Red = value.Color.ScR;
                    Item.Green = value.Color.ScG;
                    Item.Blue = value.Color.ScB;
                }
            }
        }

        // List of available colors, provided as a convenience for the xaml.
        public ColorSelection[] AvailableColors
        {
            get
            {
                return availableColors;
            }
        }

        ColorSelection[] availableColors = GetAvailableColors();

        private static ColorSelection[] GetAvailableColors()
        {
            List<ColorSelection> colors = new List<ColorSelection>();
            foreach (var pi in typeof(Colors).GetProperties())
                colors.Add(new ColorSelection { 
                    Color = (Color)pi.GetValue(null, null),
                    Name = AddSpaces(pi.Name) });
            return colors.ToArray();
        }

        // Convert from PascalCasing to human-readable.
        private static string AddSpaces(string name)
        {
            StringBuilder sb = new StringBuilder(name.Length);
            bool wasLower = false;
            for (int i = 0; i < name.Length; ++i)
            {
                if (wasLower && char.IsUpper(name[i]))
                {
                    sb.Append(' ');
                    sb.Append(char.ToLower(name[i]));
                }
                else
                {
                    sb.Append(name[i]);
                    wasLower = true;
                }
            }
            return sb.ToString();
        }

        // Proxy for a color selection
        public class ColorSelection
        {
            public Color Color { get; set; }
            public string Name { get; set; }
        }
    }
}

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 Cyest Corporation
South Africa South Africa
David is a software developer with an obsession for analysis and proper architecture.

Comments and Discussions