programming4us
programming4us
WEBSITE

Silverlight Recipes : Controls - Applying Custom Templates to a DataGrid Cell

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

1. Problem

You need a customized way of viewing and editing data that is not supported out of the box by any of the typed DataGridColumns like DataGridTextColumn or DataGridCheckBoxColumn. For example, say you want to view a color value rendered as a color stripe instead of the color name string literal.

2. Solution

Use the CellTemplate and the CellEditingTemplate properties of the DataGridTemplateColumn to apply custom viewing and editing templates.

3. How It Works

The various DataGridColumn types like DataGridTextColumn and DataGridCheckBoxColumn are designed to support binding to specific CLR data types, such as String and Boolean, or to types that can be automatically converted to these types. The way that the data is viewed and edited in cells of these specific column types is predetermined by the framework. However, the need for custom UIs for viewing and editing data was well anticipated; the DataGridTemplateColumn is supplied for exactly that purpose.

The DataGridTemplateColumn exposes two properties, CellTemplate and CellEditingTemplate, both of which accept data templates. When the column is data bound, the DataGrid binds the cell data item to the data template specified in CellTemplate to display the data in view mode. When the cell enters edit mode, the DataGrid switches to the CellEditingTemplate.

4. The Code

In this sample, you use a DataGrid bound to product data fetched from the AdventureWorks WCF service. The Product class exposes a Color property, which is defined as a String on the class. You bind the Color property to one of the DataGrid columns and thereby create a more intuitive interface where the user can actually view the color itself for both viewing and editing the Color value, as compared to the default string editing experience exposed by the DataGridTextColumn. Listing 1 shows the XAML.

Listing 1. XAML for the MainPage Used to Demonstrate Custom DataGrid Column Templates
<UserControl x:Class="Recipe5_6.MainPage"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:data=
 "clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
 xmlns:local="clr-namespace:Recipe5_6"
 Width="800" Height="400"

>

					  

<UserControl.Resources>
    <local:ColorNameToBrushConverter x:Key="REF_ColorNameToBrushConverter"/>
    <DataTemplate x:Key="dtColorViewTemplate">
      <Border CornerRadius="5,5,5,5" BorderBrush="Black"
              BorderThickness="1,1,1,1" VerticalAlignment="Stretch"
              HorizontalAlignment="Stretch" Margin="1,1,1,1"
              Background="{Binding Color,
                Converter={StaticResource REF_ColorNameToBrushConverter}}"/>
    </DataTemplate>
    <DataTemplate x:Key="dtColorEditingTemplate">
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ListBox Grid.Row="0" VerticalAlignment="Stretch"
                 HorizontalAlignment="Stretch"
                 ItemsSource="{Binding ColorList}"
                 SelectedItem="{Binding Color, Mode=TwoWay}"
                 Height="200">
          <ListBox.ItemTemplate>
            <DataTemplate>
              <Border CornerRadius="5,5,5,5" BorderBrush="Black"
                      BorderThickness="1,1,1,1" Height="25" Width="70"
                      Margin="2,5,2,5"
                      Background=
                      "{Binding Converter=
                          {StaticResource REF_ColorNameToBrushConverter}}"/>
            </DataTemplate>
          </ListBox.ItemTemplate>
        </ListBox>
      </Grid>
    </DataTemplate>
  </UserControl.Resources>
  <Grid x:Name="LayoutRoot" Background="White">
    <data:DataGrid x:Name="dgProducts" AutoGenerateColumns="False">
      <data:DataGrid.Columns>
        <data:DataGridTextColumn Binding="{Binding ProductID}"
                                 Header="ID" />
        <data:DataGridTextColumn Binding="{Binding Name}"
                                 Header="Name" />
        <data:DataGridTemplateColumn
          CellTemplate="{StaticResource dtColorViewTemplate}"
          CellEditingTemplate="{StaticResource dtColorEditingTemplate}"
          Header="Color" Width="100"/>

					  

</data:DataGrid.Columns>
    </data:DataGrid>
  </Grid>
</UserControl>

In the DataGrid declaration named dgProducts, you use a DataGridTemplateColumn to bind to Product.Color. To get the custom UI for viewing and editing the Color property, you define two data templates, dtColorTemplate and dtColorEditingTemplate, and use them to set the CellTemplate and the CellEditingTemplate properties.

In view mode, where the bound DataGridTemplateColumn uses the CellTemplate to bind the data, you bind the Color value to the Background property of a Border, as shown in the dtColorViewTemplate template. In edit mode, where CellEditingTemplate is used, dtColorEditingTemplate uses a ListBox to display the list of available colors. The ListBox.SelectedItem is bound to Product.Color to represent the currently selected color. The binding mode is set to TwoWay so that any changes made by the user updates the Product instance and is reflected in the DataGrid when the cell moves out of edit mode.

Listing 2 shows the codebehind for the page.

Listing 2. Codebehind for the MainPage Demonstrating Custom DataGrid Column Templates
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using Recipe5_6.AdvWorks;

namespace Recipe5_6
{
  public partial class MainPage : UserControl
  {
    AdvWorksDataServiceClient client =
      new AdvWorksDataServiceClient();
    bool EditingColor = false;
    public MainPage()
    {
      InitializeComponent();
      GetData();
    }

    private void GetData()
    {
      client.GetProductsCompleted +=
        new EventHandler<GetProductsCompletedEventArgs>(
          delegate(object sender, GetProductsCompletedEventArgs e)

					  

{
            dgProducts.ItemsSource = e.Result;
          });

      client.GetProductsAsync();
    }
  }


  public class ColorNameToBrushConverter : IValueConverter
  {
    //convert from a string Color name to a SolidColorBrush
    public object Convert(object value, Type targetType,
      object parameter, System.Globalization.CultureInfo culture)
    {
      //substitute a null with Transparent
      if (value == null)
        value = "Transparent";
      //make sure the right types are being converted
      if (targetType != typeof(Brush) || value.GetType() != typeof(string))
        throw new NotSupportedException(
          string.Format("{0} to {1} is not supported by {2}",
          value.GetType().Name,
          targetType.Name,
          this.GetType().Name));

      SolidColorBrush scb = null;
      try
      {
        //get all the static Color properties defined in
        //System.Windows.Media.Colors
        List<PropertyInfo> ColorProps = typeof(Colors).
          GetProperties(BindingFlags.Public | BindingFlags.Static).ToList();
        //use LINQ to find the property whose name equates
        //to the string literal we are trying to convert
        List<PropertyInfo> piTarget = (from pi in ColorProps
                                       where pi.Name == (string)value
                                       select pi).ToList();
        //create a SolidColorBrush using the found Color property.
        //If none was found i.e. the string literal being converted
        //did not match any of the defined Color properties in Colors
        //use Transparent
        scb = new SolidColorBrush(piTarget.Count == 0 ?
          Colors.Transparent : (Color)(piTarget[0].GetValue(null, null)));
      }
      catch

					  

{
        //on exception, use Transparent
        scb = new SolidColorBrush(Colors.Transparent);
      }
      return scb;


    }
    //convert from a SolidColorBrush to a string Color name
    public object ConvertBack(object value, Type targetType,
      object parameter, System.Globalization.CultureInfo culture)
    {
      //make sure the right types are being converted
      if (targetType != typeof(string) || value.GetType() != typeof(Brush))
        throw new NotSupportedException(
          string.Format("{0} to {1} is not supported by {2}",
          value.GetType().Name,
          targetType.Name,
          this.GetType().Name));

      string ColorName = null;
      try
      {
        //get all the static Color properties defined
        //in System.Windows.Media.Colors
        List<PropertyInfo> ColorProps = typeof(Colors).
          GetProperties(BindingFlags.Public | BindingFlags.Static).ToList();
        //use LINQ to find the property whose value equates to the
        //Color on the Brush we are trying to convert
        List<PropertyInfo> piTarget = (from pi in ColorProps
                                       where (Color)pi.GetValue(null, null)
                                       == ((SolidColorBrush)value).Color
                                       select pi).ToList();
        //If a match is found get the Property name, if not use "Transparent"
        ColorName = (piTarget.Count == 0 ? "Transparent" : piTarget[0].Name);
      }
      catch
      {
        //on exception use Transparent
        ColorName = "Transparent";
      }
      return ColorName;
    }
  }
}

					  

namespace Recipe5_6.AdvWorks
{
  public partial class Product
  {
    private ObservableCollection<string> _ColorList;
    //color literals defined in System.Windows.Media.Colors
    public ObservableCollection<string> ColorList
    {
      get
      {
        return new ObservableCollection<string> {
        "Black",
        "Blue",
        "Brown",
        "Cyan",
        "DarkGray",
        "Gray",
        "Green",
        "LightGray",
        "Magenta",
        "Orange",
        "Purple",
        "Red",
        "Transparent",
        "White",
        "Yellow" };
      }
    }
  }
}

					  

The ListBox.ItemsSource is bound to the Product.ColorList property, defined in a partial extension of the Product proxy data type, which returns a collection of string literals representing names of the Color properties, as defined in the System.Windows.Media.Colors type. To display each item, an ItemTemplate similar to that in the view mode is used, where a Border is used to display the color choice by binding the Color value to Border.Background.

Figure 1 compares the DataGrid Color column in view mode and edit mode.

Figure 1. The Color column in view mode (left) and edit mode (right)

Also note in Listing 2 the use of a value converter of type ColorNameToBrushConverter. Since the Border.Background property is of type SolidColorBrush and Product.Color is a string literal, you need to facilitate an appropriate value conversion. Listing 5-11 shows the value converter code as well in the ColorNameToBrushConverter class. 

In both the conversion functions in the value converter implementation, you use reflection to enumerate the list of static properties of type Color defined on the type System.Windows.Media.Colors, each of which are named for the Color they represent. In Convert(), while trying to convert a Color name string to a SolidColorBrush, you find the matching Color property in the enumerated list of properties and use that to create and return the brush. In ConvertBack(), while trying to convert a SolidColorBrush to a color name string, you find the property with a Color value matching the SolidColorBrush.Color and use the property name as the color name string. If no matches are found or if exceptions occur, it falls back to Colors.Transparent as the default value.

Other  
 
Top 10
Free Mobile And Desktop Apps For Accessing Restricted Websites
MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
TOYOTA CAMRY 2; 2.5 : Camry now more comely
KIA SORENTO 2.2CRDi : Fuel-sipping slugger
How To Setup, Password Protect & Encrypt Wireless Internet Connection
Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
Backup & Restore Game Progress From Any Game With SaveGameProgress
Generate A Facebook Timeline Cover Using A Free App
New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
- Messages forwarded by Outlook rule go nowhere
- Create and Deploy Windows 7 Image
- How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
- Creating and using an unencrypted cookie in ASP.NET
- Directories
- Poor Performance on Sharepoint 2010 Server
- SBS 2008 ~ The e-mail alias already exists...
- Public to Private IP - DNS Changes
- Send Email from Winform application
- How to create a .mdb file from ms sql server database.......
programming4us programming4us
programming4us
 
 
programming4us