Click here to Skip to main content
15,891,607 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello!

I have the following requirement: I have a list of object instances where each instance has a property of a type I do not know at runtime (e.g. DateTime, string or int). I want to fill a datagrid with that list and for the afore mentioned property, show the appropriate editor when the cell is selected.

I am trying to accomplish this with a custom control like the code shows below:
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DataGridExample
{
    public class UniversalControl : ContentControl
    {
        public UniversalControl()
        {
            this.DefaultStyleKey = typeof(UniversalControl);
        }

        public object Value
        {
            get
            {
                return this.GetValue(ValueProperty);
            }
            set
            {
                this.SetValue(ValueProperty, value);
            }
        }

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register(
                "Value",
                typeof(object),
                typeof(UniversalControl),
                new PropertyMetadata(null, ValuePropertyChanged));

        private static void ValuePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
        {
            DatePicker picker = new DatePicker();
            if (eventArgs.NewValue != null && eventArgs.NewValue is DateTime)
                picker.SelectedDate = (DateTime)eventArgs.NewValue;

            ((UniversalControl)sender).Content = picker;
            ((UniversalControl)sender).Visibility = Visibility.Visible;
        }

        public override void OnApplyTemplate()
        {
             base.OnApplyTemplate();
        }
    }
}


So, in the valuechanged handler I create the control which goes with the bound value (in this example only the datepicker, but it is about the idea).

Anyway, the result is that I do not see anything happening, while the debugger stops in the handler and I can see the code creating the control being executed.

Anyone has an idea what this could be?

Regards, Perry
Posted
Updated 29-Mar-11 14:17pm
v2

1 solution

You can accomplish this using CellTemplate (the property name should be similar) for the Column.

Write a DataTemplate with DataTriggers. These DataTrigger would help in showing and hiding the different controls.


Lets go to your problem:
Did you checked whether the ValueChanged handler executes all the times (it should be equal to the number of items in the list)?

Thing I noticed:
Even the data is not DateTime it would show the control. It should be like below
C#
if (eventArgs.NewValue != null && eventArgs.NewValue is DateTime)
{
    picker.SelectedDate = (DateTime)eventArgs.NewValue;
    ((UniversalControl)sender).Content = picker;
    ((UniversalControl)sender).Visibility = Visibility.Visible;
}


The below code might throw runtime error if the eventArgs.NewValue is null. Avoid using && operator while checking for != null
C#
if (eventArgs.NewValue != null && eventArgs.NewValue is DateTime)


Suggestion:
Instead of casting UniversalControl everytime you can define a variable at the beginning of the method and start using it.

Update:
UniversalControl style doesn't have any ContentPresenter to show the Content you add dynamically from the codebehind.

It should be like below:

XML
<Style TargetType="local:UniversalControl">
        <setter property="Template">
            <setter.value>
                <controltemplate targettype="local:UniversalControl">
                    <border removed="{TemplateBinding Background}">
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <contentpresenter />
                    </border>
                </controltemplate>
            </setter.value>
        </setter>
    </Style>


See, I have added a ContentPresenter to show the Content. :)

Mark it as Answer if it is helpful.
 
Share this answer
 
v4
Comments
Perry Bruins 30-Mar-11 0:39am    
Hi Venkatesh,

I know the code is not flawless, I am just pondering and trying things before diving into real production code.
About your answer: I thought about using DataTriggers too, but I am not sure if this concept is available in Silverlight (I know it is in WPF though).

The thing is that I can see the code being executed and creating the control, but it is just not showing.

If you are curious about the rest of the code, I have placed the complete project here http://dl.dropbox.com/u/3693471/DataGridExample_customcontrol.rar

Thanks for your time and thoughts!

Regards, Perry
Venkatesh Mookkan 30-Mar-11 0:58am    
Got the source. Let me check and get back.
Venkatesh Mookkan 30-Mar-11 1:16am    
I found the issue in your code. Answer has been updated. Happy coding!
Sandeep Mewara 30-Mar-11 2:14am    
Good answer. My 5!
Venkatesh Mookkan 30-Mar-11 2:25am    
Thank you

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900