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

Confusion regarding Cell binding to a dynamic DataTable

5 Answers 148 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Noah
Top achievements
Rank 1
Noah asked on 27 Aug 2010, 06:47 PM
Perhaps I am simply misunderstanding the correct way to bind to a given cell in general, but here's my problem.

I have a grid full of cells of type StatisticCell which looks like this:

[DataContract]
public class StatisticCell
{
    [DataMember]
    public string Value { get; set; }
 
    [DataMember]
    public bool IsSelected { get; set; }
 
    public StatisticCell(string value, bool isSelected)
    {
        Value = value;
        IsSelected = isSelected;
    }
}

Which is bound dynamically on the client into a RadGridView using the DataTable class provided here.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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;
using System.ComponentModel;
using System.Windows.Data;
 
using Telerik.Data;
using Telerik.Windows.Controls;
 
using DFA.Client.QueryToolService;
using DFA.Client.ValueConverter;
 
namespace DFA.Client.QueryTool.Control.Panes
{
    public partial class StatisticsContent : UserControl
    {
        public StatisticsContent()
        {
            InitializeComponent();         
        }
 
        public string Title
        {
            get { return "Statistics"; }
        }
 
        private DataTable _DataTable;
 
        public void LoadStatistics(ObservableCollection<StatisticRow> rows)
        {
            _DataTable = new DataTable();
 
            foreach (var axis in rows.First().Data.Keys)
            {              
                _DataTable.Columns.Add(new DataColumn() { ColumnName = axis, DataType = typeof(StatisticCell) });              
            }
 
            foreach (StatisticRow row in rows)
            {
                var dataRow = _DataTable.NewRow();
 
                foreach (var axis in row.Data.Keys)
                {
                    dataRow[axis] = row.Data[axis];
                }
 
                _DataTable.Rows.Add(dataRow);
            }
 
            _StatisticsGridView.ItemsSource = _DataTable;
        }
 
 
        private void _StatisticsGridView_BeginningEdit(object sender, Telerik.Windows.Controls.GridViewBeginningEditRoutedEventArgs e)
        {
             
        }
 
        private void _ApplyButton_Click(object sender, RoutedEventArgs e)
        {          
            Cursor = Cursors.Wait;
        }
 
        private void _ResetButton_Click(object sender, RoutedEventArgs e)
        {
        }
 
        private void _StatisticsGridView_AutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e)
        {          
            e.Column.CellTemplate = (DataTemplate)Resources["_CellTemplate"];
        }
    }
}

With XAML:
<UserControl x:Class="DFA.Client.QueryTool.Control.Panes.StatisticsContent"
    xmlns:converters="clr-namespace:DFA.Client.ValueConverter"
    mc:Ignorable="d"
   d:DesignHeight="300" d:DesignWidth="400"
    <UserControl.Resources>
        <converters:BooleanToBackgroundConverter x:Key="BooleanToBackgroundConverter"/>
 
        <DataTemplate x:Name="_CellTemplate" >
            <StackPanel  Orientation="Horizontal" Background="Yellow" >
                <TextBlock Text="{Binding Path=Value}">
                </TextBlock>
            </StackPanel>
        </DataTemplate>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <telerik:RadGridView
                x:Name="_StatisticsGridView"
                CanUserReorderColumns="False"                
                CanUserInsertRows="False" CanUserDeleteRows="False" CanUserFreezeColumns="False"
                ShowGroupPanel="False" ShowColumnHeaders="True"
                AutoGenerateColumns="True"
                CanUserSelect="False" BeginningEdit="_StatisticsGridView_BeginningEdit"
                Margin="0,0,12,49" SelectionUnit="Cell" IsFilteringAllowed="False" RowIndicatorVisibility="Collapsed" AutoGeneratingColumn="_StatisticsGridView_AutoGeneratingColumn">           
        </telerik:RadGridView>
        
        <Button Content="Apply" Height="23" HorizontalAlignment="Right" Margin="0,0,100,12" Name="_ApplyButton" VerticalAlignment="Bottom" Width="75" Click="_ApplyButton_Click" IsEnabled="{Binding IsDirty}" />
        <Button Content="Reset" Height="23" HorizontalAlignment="Right" Margin="0,0,12,12" Name="_ResetButton" VerticalAlignment="Bottom" Width="75" Click="_ResetButton_Click" IsEnabled="{Binding IsDirty}" />
 
    </Grid>
</UserControl>


My problem is that if I don't use a CellTemplate each cell correctly renders a StatisticCell.ToString() however when I bind, my BindingContext is always the dynamic row instead of the cell.  For example an error in binding from above would be:

System.Windows.Data Error: BindingExpression path error: 'Value' property not found on 'DynamicObjectBuilder_a6f7b2a9-102e-4099-8aed-f404f55b601a' 'DynamicObjectBuilder_a6f7b2a9-102e-4099-8aed-f404f55b601a' (HashCode=18537444). BindingExpression: Path='Value' DataItem='DynamicObjectBuilder_a6f7b2a9-102e-4099-8aed-f404f55b601a' (HashCode=18537444); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..

How can I get the binding context to be the cell instead of the row?  I had the exact same problem when I attempted to use the DictionaryConverter class provided in another thread.  I assume I'm using either the wrong template or misunderstand how to index into the cell within the binding.  Help!

5 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 30 Aug 2010, 08:03 AM
Hello,

 It will be better if you construct your cell template dynamically and provide binding for valid property or you can use our template selectors

Best wishes,
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
Noah
Top achievements
Rank 1
answered on 30 Aug 2010, 03:59 PM
Vlad, I have read the thread you linked before.  Can you explain to me why when no CellTemplate is used, the individual class instance (StatisticCell) is properly rendered in each cell via StatisticCell.ToString() but when the Template is used, the ROW is the binding context.  Is there a way to do something like {Binding Cell.Value}?
0
Vlad
Telerik team
answered on 31 Aug 2010, 06:57 AM
Hi,

 DataContext for all cells and the row itself is the data item. You can check also standard MS DataGrid - the behavior is exactly the same. You can do this (Binding to Cell.Value) however the solution is not trivial in Silverlight (unlike WPF) - you can check it here. Look for CellValueBindingBehavior.

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
John
Top achievements
Rank 1
answered on 27 Jul 2012, 02:40 PM
Of course now you can use a relative ancestor.  To get the value of the cell (post datamemberbinding) use a relative source to find the cell and bind to it's Value property

<DataTemplate x:Key="DataFlaggedCellTemplate">
 	<Border Background="Aqua">
		<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=telerik:GridViewCell, AncestorLevel=1}, Path=Value}" />
	</Border>
</DataTemplate>
0
Leah
Top achievements
Rank 1
answered on 24 Jun 2013, 08:34 AM
John,
Thank you very much for posting your update (two years after the fact!).
It has made all the difference to us.
Leah
Tags
GridView
Asked by
Noah
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Noah
Top achievements
Rank 1
John
Top achievements
Rank 1
Leah
Top achievements
Rank 1
Share this question
or