This is a migrated thread and some comments may be shown as answers.

Programmatically creating templated columns

5 Answers 271 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Finn
Top achievements
Rank 1
Finn asked on 03 Jun 2010, 12:30 PM
I'm currently evaluating the GridView component for a prototype of an application and I've run into some problems that may be a show-stopper for us. The architecture that we've decided to use requires that the columns are either autogenerated or (for customization) programmatically created from meta data.

I've investigated the problem with several approaches: HypeLinkColumn, DynamicHyperLinkColumn, programmatic cell template and finally XamlReader cell template. I suspect that the reason is the same, that is that the binding expression for some reason fail to map to the right column in the datacontext.

The following code will produce a DataTemplate that I assign to the CellTemplate. Currently this produces a HyperLink with the content 'System.Data.DataRow', however filling in the PathProperty of the Binding will produces a blank/empty string. This problem persists even though I known (or even hard code) a column name/binding path that I've confirmed is in the current datacontext.  

Is there something I've missed about Binding expression in CellTemplate !?
                        FrameworkElementFactory tbContent = new FrameworkElementFactory(typeof(TextBlock)); 
                        tbContent.SetBinding(TextBlock.TextProperty, new Binding());  
 
                        FrameworkElementFactory hl = new FrameworkElementFactory(typeof(Hyperlink)); 
                        hl.AddHandler(Hyperlink.ClickEvent, new RoutedEventHandler(hl_Click)); 
                        hl.AppendChild(tbContent); 
 
                        FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock)); 
                        tb.AppendChild(hl); 
 
                        DataTemplate dTemp = new DataTemplate(); 
                        dTemp.VisualTree = tb
                        dTemp.Seal(); 

5 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 03 Jun 2010, 12:40 PM
Hi,

It will be better if you inherit from desired grid column type, override CreateCellElement and/or CreateCellEditElement and return desired FrameworkElement. You can check for example this blog post.

Kind regards,
Vlad
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Finn
Top achievements
Rank 1
answered on 03 Jun 2010, 01:05 PM
Hi, Vlad

Thank you for your reply, I'll try this approach right away, and get back to you if the binding problem persists.

Regards,
Finn
0
Pablo Tola
Top achievements
Rank 2
answered on 03 Jun 2010, 04:10 PM
I like your blog post, and I think it will be a great solution for a control I need to create.
It's a DynamicComboBox, depending on the need it will allow single or multiple item selection.
I've created a user control following some examples I've found on the forums that allows multiple item selection, I was looking to somehow tell the grid to show either the radcombobox or the user control I created depending on my needs, but your solutions seems like the right way to do it, overriding the CreateCellEditElement and return either one based on a property value.

Could you please point me in the right direction looking at my control files I've attached on how to achieve this.
I just realized... you don't allow .zip upload... I'm copying the code below.

Thank you.

cs file

using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Linq;  
using System.Windows;  
using System.Windows.Controls;  
 
namespace MarsResearch.Survey.Common.Controls  
{  
    /// <summary>  
    /// Interaction logic for CheckBoxComboBox.xaml  
    /// </summary>  
    public partial class CheckBoxComboBox : UserControl  
    {  
 
        public CheckBoxComboBox()  
        {  
            InitializeComponent();  
 
            ItemsCombo.SelectionChanged += ItemsCombo_SelectionChanged;  
            ItemsCombo.DropDownClosed += ItemsCombo_DropDownClosed;  
 
        }  
 
        void ItemsCombo_DropDownClosed(object sender, EventArgs e)  
        {  
            SelectedItems = Choices;  
        }  
 
        void ItemsCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)  
        {  
            SelectedItems = Choices;  
        }
        #region Dependency Properties  
 
        public List<DataItem> ItemsSource  
        {  
            get { return (List<DataItem>)GetValue(ItemsSourceProperty); }  
            set 
            {  
                SetValue(ItemsSourceProperty, value);  
            }  
        }  
 
        public static readonly DependencyProperty ItemsSourceProperty =  
            DependencyProperty.Register("ItemsSource"typeof(List<DataItem>), typeof(CheckBoxComboBox), new UIPropertyMetadata(null));  
 
        public string SelectedItems  
        {  
            get { return (string)GetValue(SelectedItemsProperty); }  
            set { SetValue(SelectedItemsProperty, value); }  
        }  
 
        public static readonly DependencyProperty SelectedItemsProperty =  
            DependencyProperty.Register("SelectedItems"typeof(string), typeof(CheckBoxComboBox), new UIPropertyMetadata(string.Empty));
        #endregion  
 
        public string Choices  
        {  
            get 
            {  
                return string.Join(",", ItemsSource.Where(d => d.IsChecked).Select(item => item.Value.ToString()).ToArray());  
            }  
        }  
 
        public void OnCheckedStateChanged()  
        {  
            if (this.PropertyChanged != null)  
            {  
                this.PropertyChanged(thisnew PropertyChangedEventArgs("SelectedItems"));  
                this.PropertyChanged(thisnew PropertyChangedEventArgs("Choices"));  
            }  
        }  
 
        public event PropertyChangedEventHandler PropertyChanged;  
 
    }  
 
    public class DataItem  
    {  
 
        private bool _isChecked;  
        public bool IsChecked  
        {  
            get 
            {  
                return _isChecked;  
            }  
            set 
            {  
                _isChecked = value;  
                Owner.OnCheckedStateChanged();  
            }  
        }  
 
        public double Value { getset; }  
        public string Text { getset; }  
 
        public CheckBoxComboBox Owner { getset; }  
 
    }  
 

xaml file

<UserControl x:Class="MarsResearch.Survey.Common.Controls.CheckBoxComboBox" 
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   
             xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"   
             mc:Ignorable="d" x:Name="CheckBoxComboBoxControl" > 
    <UserControl.Resources> 
        <DataTemplate x:Key="SelectionBoxTemplate">  
            <TextBlock Text="{Binding Owner.Choices}" MinWidth="100"/>  
        </DataTemplate> 
    </UserControl.Resources> 
    <telerik:RadComboBox x:Name="ItemsCombo" SelectionBoxTemplate="{StaticResource SelectionBoxTemplate}" 
        ItemsSource="{Binding ItemsSource, ElementName=CheckBoxComboBoxControl}" MinWidth="100" > 
        <telerik:RadComboBox.ItemTemplate> 
            <DataTemplate> 
                <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding Text}" /> 
            </DataTemplate> 
        </telerik:RadComboBox.ItemTemplate> 
    </telerik:RadComboBox> 
      
</UserControl> 
 
0
Vlad
Telerik team
answered on 03 Jun 2010, 04:19 PM
Hi,

You can cast the second argument to your object type in CreateCellEditElement method and check desired property directly to see what should be returned.

Kind regards,
Vlad
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Finn
Top achievements
Rank 1
answered on 04 Jun 2010, 09:39 AM
Hi, Vlad 

I'm happy to report that the solution worked for me. Via dataitem parameter of this method, I could easily render the
desired controls and settings.

Regards,
Finn
Tags
GridView
Asked by
Finn
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Finn
Top achievements
Rank 1
Pablo Tola
Top achievements
Rank 2
Share this question
or