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

RadGridView - Pasting from excel

4 Answers 294 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Charles
Top achievements
Rank 1
Charles asked on 16 Oct 2017, 04:13 PM

How may I configure RadGridView to allow pasting of multiple rows of data?  I am able to paste over existing selected rows, but when I need to paste more rows than are in the RadGridView it just stops at the last existing row.

This can't be a new requirement, and I imagine there is just some documentation I can't find with my google foo... I found a few very old posts about manually handling pasting from the clipboard, but they were nearly a decade old.

Basically, I'd like to use the RadGridView to manage x, y, z data rows.  It would start empty, and then be able to paste n rows from Excel into the empty grid.  Is this possible?  I was able to do it with the Spreadsheet control, but it's rather slow to load and crashes on occasion when disposing. 

Thanks in advance!

4 Answers, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 19 Oct 2017, 07:55 AM
Hello, Charles,    

Thank you for writing back. 

Your question has already been answered in the other thread you have opened on the same topic "Pasting new rows from Excel into RadGridView". Please, see our answer there for more information.
We kindly ask you to use just one thread for a specific problem to contact us. Posting the same questions numerous times slows down our response time because we will need to review and address two or more tickets instead of one. Moreover, threads are handled according to license and time of posting, so if it is an urgent problem, we suggest you use a support ticket, which would be handled before a forum thread.

Thank you for your understanding.

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Charles
Top achievements
Rank 1
answered on 22 Oct 2017, 01:17 AM

The generic (assuming the datasource implements IList) solution I came up with which allows you to paste from Excel when the gridview is empty or populated while adding rows if over running existing rows, for anyone googling a solution.  I used CsvHelper to reliably parse the string from the clipboard to a dynamic object.  The properties are them mapped in order when it is possible to convert to the property so that it supports partial columns. I wanted to use AutoMapper for that part, but doing an optimistic index based mapping with it looks to be more of a hassle than just doing it manually.

 

public class CustomGrid : RadGridView
{
    protected override RadGridViewElement CreateGridViewElement()
    {
        return new CustomRadGridViewElement();
    }
 
    public override string ThemeClassName => typeof(RadGridView).FullName;
}
 
public class CustomRadGridViewElement : RadGridViewElement
{
    protected override MasterGridViewTemplate CreateTemplate()
    {
        return new CustomMasterGridViewTemplate();
    }
 
    protected override Type ThemeEffectiveType => typeof(RadGridViewElement);
}
 
public class CustomMasterGridViewTemplate : MasterGridViewTemplate
{
    public static bool CanChangeType(object value, Type conversionType)
    {
        if (conversionType == null)
        {
            return false;
        }
 
        if (value == null)
        {
            return false;
        }
 
        IConvertible convertible = value as IConvertible;
 
        if (convertible == null)
        {
            return false;
        }
 
        return true;
    }
 
    public override void Paste()
    {
        if (Clipboard.ContainsData(DataFormats.Text))
        {
            var dataSource = this.Owner.DataSource as IList;
            if (dataSource != null)
            {
                string data = Clipboard.GetData(DataFormats.Text).ToString();
                if (!string.IsNullOrWhiteSpace(data))
                {
                    using (TextReader reader = new StringReader(data))
                    {
                        var csv = new CsvReader(reader, new Configuration(){HasHeaderRecord = false, Delimiter = "\t"});
                        IEnumerable<object> records = null;
                        var type = dataSource.GetType().GetGenericArguments().Single();
                        try
                        {
                            records = csv.GetRecords<dynamic>().ToList();
                            var count = records.Count();
                        }
                        catch { }
 
                        if (records != null)
                        {
                            var rowIndex = 0;
                            if (this.Owner.SelectedCells.Any())
                                rowIndex = this.Owner.SelectedCells.Select(c => c.RowInfo.Index).Min();
                            if (this.Owner.SelectedRows.Any())
                                rowIndex = this.Owner.SelectedRows.Select(r => r.Index).Min();
                            if (rowIndex == -1)
                                rowIndex = this.Owner.RowCount;
 
                            foreach (var record in records)
                            {
                                if (dataSource.Count == rowIndex)
                                {
                                    dataSource.Add(Activator.CreateInstance(type));
                                }
                                var propertyValues = (IDictionary<string, object>)record;
                                var properties = dataSource[rowIndex].GetType().GetProperties();
                                var propertyIndex = 0;
                                foreach (var propertyValue in propertyValues)
                                {
                                    while (!CanChangeType(propertyValue.Value, properties[propertyIndex].PropertyType) && propertyIndex < properties.Length)
                                    {
                                        propertyIndex++;
                                    }
 
                                    if (propertyIndex < properties.Length)
                                    {
                                        var value = Convert.ChangeType(propertyValue.Value, properties[propertyIndex].PropertyType);
                                        properties[propertyIndex].SetValue(dataSource[rowIndex], value);
                                    }
                                }
                                rowIndex++;
                            }
                            this.Refresh();
                            return;
                        }
                    }
                }
            }
        }
        base.Paste();
    }
}

 

 

 

 

0
Charles
Top achievements
Rank 1
answered on 22 Oct 2017, 01:21 AM

Missed a line in the paste, but this should be used for the value assignment.  The above missed the propertyIndex++ after writing the value.  

 

if (propertyIndex < properties.Length)
{
    var value = Convert.ChangeType(propertyValue.Value, properties[propertyIndex].PropertyType);
    properties[propertyIndex].SetValue(dataSource[rowIndex], value);
    propertyIndex++;
}
0
Accepted
Dess | Tech Support Engineer, Principal
Telerik team
answered on 23 Oct 2017, 11:06 AM
Hello, Charles,    

Thank you for writing back. 

I am glad that the suggested approach in the support thread that you have on the same topic was useful. Thank you for sharing your solution with the community and someone can benefit from it.

If you have any additional questions, please let me know. 

 Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
GridView
Asked by
Charles
Top achievements
Rank 1
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Charles
Top achievements
Rank 1
Share this question
or