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

Copy Clipboard operation shows class name when used on grid with dynamically created columns

5 Answers 61 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Domagoj
Top achievements
Rank 1
Domagoj asked on 13 Dec 2011, 10:38 AM
Hi!
I'm trying to implement the Copy mechanism, but I have a serious problem.

My Datagrid is bound to a ObservableCollection<MyRow>. Here is the MyRow class

public class MyRow 
{
    public List<string> ColumnNames { get; set; }
    public List<decimal?> Values { get; set; }
          
    public String TimeStamp { get; set; }
  
    public MyRow () 
    {
        ColumnNames = new List<string>();
        Values = new List<decimal?>();
    }
}

As you can see, the columns are created dynamically, because the MyRow object can hold an arbitrary number of values (so that number of columns would have to be made). The columns are generated for each String in ColumnNames and the values are bound by using the parameterized ValueConverter.

private void createColumns(ObservableCollection<MyRow> values)
{
    while (dataGrid.Columns.Count > 1)
        dataGrid.Columns.RemoveAt(1);
  
    dataGrid.Columns[0].Header = CommonStrings.TimeStamp;
    int columnCount = values.First().ColumnNames.Count;
  
    for (int i = 0; i < columnCount; i++)
    {
        GridViewDataColumn col = new GridViewDataColumn();
        col.Header = values.First().ColumnNames[i];
        col.DataType = typeof(MyRow);
        Binding bnd = new Binding();
        bnd.Converter = new MyRowCollectionConverter(); 
        bnd.ConverterParameter = i;
        col.DataMemberBinding = bnd;
        dataGrid.Columns.Add(col);
    }
}

However, when I try to Copy (CTRL+C), this is what I get.

TimeStamp               Value1 
12.12.2011. 9:51:59     MyProject.MyRow
12.12.2011. 9:52:59     MyProject.MyRow
12.12.2011. 9:53:59     MyProject.MyRow
12.12.2011. 9:54:59     MyProject.MyRow

Value1 is the name contained in the List<String> ColumnNames. That part is ok. However, I don't get the data (which are the decimal values, like 0.242524312), but instead I get the class name.

What can I do to make the copy operation retain the values in the bound property of the MyRow object instead of its class name (I guess it calls the ToString() method on whatever is inside).

5 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 16 Dec 2011, 10:39 AM
Hello,

 We are using similar approach on this demo however copy works as expected. 

Best wishes,
Vlad
the Telerik team

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

0
Domagoj
Top achievements
Rank 1
answered on 20 Dec 2011, 08:10 AM

After an hour rummaging through your demo example, I have finally spotted the difference between your code and mine.

The thing is, I was binding to the object itself (the instance of MyRow class). That's why the constructor of the Binding is empty.

What I was supposed to do is bind to the MyRow.Values property.

So, here is the working solution:

The same loop,

for (int i = 0; i < columnCount; i++)  
{  
    GridViewDataColumn col = new GridViewDataColumn();  
    col.Header = values.First().ColumnNames[i];  
    col.DataType = typeof(MyRow);  
    Binding bnd = new Binding("Values");  
    bnd.Converter = new MyRowCollectionConverter();  
    bnd.ConverterParameter = i;  
    col.DataMemberBinding = bnd;  
    dataGrid.Columns.Add(col);  
}

And then the value converter:

public class MyRowCollectionConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        List<Decimal?> list = value as List<Decimal?>;
        return list[(int)parameter];
    }
  
    // ... ConvertBack() not implemented (excluded for brevity)
}

Thanks for the help.

0
Domagoj
Top achievements
Rank 1
answered on 22 Dec 2011, 04:22 PM

I have an additional problem related to this scenario.

When I have dynamic number of columns, I am unable to sort by those columns in the grid. 

I don't know if the underlying type of Decimal? has anything to do with the sorting. It is nullable so I don't know.

If this does present a problem, what would be the solution for implementing the sorting (all nullables go before or after all other sorted items that have a value)?

Thanks in advance.

0
Vlad
Telerik team
answered on 27 Dec 2011, 08:52 AM
Hi,

 You need to check if your column DataType is IComparable - only in this case you will be able to sort the column.

Greetings,
Vlad
the Telerik team

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

0
Domagoj
Top achievements
Rank 1
answered on 02 Jan 2012, 11:28 AM

The only way for this scenario to work was to set the cell's DataType to typeof(MyRow), because of the binding.

However, if you take a look at the MyRow class, you will see that it is impossible to meaningfully implement IComparable since the IComparable.CompareTo method would have to know the index of the element the two MyRow instances are compared by.

What would be the right way to approach this problem?

Tags
GridView
Asked by
Domagoj
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Domagoj
Top achievements
Rank 1
Share this question
or