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

Cannot Get CellTemplate to Bind to Converted Value

2 Answers 75 Views
GridView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Nick
Top achievements
Rank 1
Nick asked on 09 Jul 2012, 03:56 PM
I am currently using a RadGridView to bind to a List of Row objects. Let's call them PersonRows. Each PersonRow has on it a collection of Tasks, which can have various states. It is my intention that each column in the RadGridView corresponds to a single element in the collection of tasks on each person. The list of tasks cannot be known at compile time, and is loaded from a database, therefore I have to construct the columns and perform the bindings at runtime. I am using a ValueConverter in order to accomplish the binding. First I construct the column, like so:

foreach (Task task in this.PersonStatusListingViewModel.ConfiguredTasks)
{
  Telerik.Windows.Controls.GridViewDataColumn taskColumn = new Telerik.Windows.Controls.GridViewDataColumn();
  taskColumn.UniqueName = task.ID.ToString();
  Binding binding = new Binding();
  binding.ConverterParameter = taskColumn.UniqueName;
  TaskValueConverter conv = new TaskValueConverter();
  binding.Converter = conv;
  taskColumn.DataMemberBinding = binding;
  taskColumn.CellTemplate = (DataTemplate)this.Resources["TaskTemplate"];
  taskColumn.Header = task.Description;
  PersonGrid.Columns.Add(taskColumn);
}

The ValueConverter:

public class TaskValueConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      int? currentIndex = null;
      PersonViewModel person = (PersonViewModel)value;
      ObservableCollection<TaskViewModel> TaskVMs = person.TaskViewModels;
      for (int i = 0; i < TaskVMs.Count; i++)
      {
        if (TaskVMs[System.Convert.ToInt32(i)].taskID.ToString() == parameter)
          currentIndex = i;
      }
 
      if (currentIndex != null)
      {
        return TaskVMs[System.Convert.ToInt32(currentIndex)];
      }
      else
        return null;
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }

By overriding .ToString() on the individual tasks, I can confirm that the columns are each binding to the proper item in the Task collection on each person. The column binding itself seems to be working properly, and is not the problem. The problem comes with the DataTemplate I am adding to the column. The DataTemplate is nothing more than a series of controls to manipulate the task objects (in progress, complete, and so on). However, I can see while debugging that the DataTemplate is using the DataContext of the GridView itself (PersonRow), and not the actual binding on each column (specific Task object). For instance, the DataTemplate binding for "TaskStarted" will attempt to bind to "PersonRow.TaskStarted", but it needs to bind to "Task.TaskStarted." How can I set up the DataTemplate to correctly bind to the Task of each person?

2 Answers, 1 is accepted

Sort by
0
Accepted
Pavel Pavlov
Telerik team
answered on 12 Jul 2012, 08:22 AM
Hi Nick ,

DataMember binding is used when RadGridView creates its default display and edit elements e.g. textboxes.
When you define your own data template.  RadGridView does not know which element in the data template is the one to bind .  This means that when you use your own data template you need to set the binding explicitly for the control inside . For example - if you have a textbox inside  instead of :

<DataTemplate>
<TextBox />
</DataTemplate>

you should do :

<DataTemplate>
<TextBox Text={Binding MyProperty} />
</DataTemplate>

I understand that in your case this is not directly possible as you create columns and binding dynamically based on a collection of your person row object.

In this case you can create and set the template from code behind using XamlReader.Load . This way you can build a string containing a valid XAML with the proper binding path and create a DataTemplate from it.

Let me know in case you have troubles with this approach or need additional assistance.

Regards,
Pavel Pavlov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Nick
Top achievements
Rank 1
answered on 12 Jul 2012, 04:33 PM
Thank you, after much trial and error I actually ended up doing exactly this. It's still good to know that my solution isn't entirely crazy though. With luck the answer can still assist others.
Tags
GridView
Asked by
Nick
Top achievements
Rank 1
Answers by
Pavel Pavlov
Telerik team
Nick
Top achievements
Rank 1
Share this question
or