System.NullReferenceException when Cell Copy

Hi,

I have a sfdatagrid with two properties binded to one of the columns using template with Run.

When I want to copy such cell I get System.NullReferenceException. For standard cells it works ok.


<syncfusion:GridTemplateColumn HeaderText="UPS" MinimumWidth="80" Width="80">
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource upsListTextBlockStyle}">
<Run Text="" />
<Run Text="{Binding UpsFamilly.Name}" />
<Run Text=" " />
<Run Text="{Binding UpsUnit.UpsOutputConfiguration}" />
</TextBlock>
</StackPanel>
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
</syncfusion:GridTemplateColumn>


<syncfusion:GridTextColumn HeaderText="Units" MappingName="UnitsNumber" MinimumWidth="50" MaximumWidth="50" />
<syncfusion:GridTextColumn HeaderText="Configuration" MappingName="Configuration" MinimumWidth="100" />

Regards

Jakub


3 Replies 1 reply marked as answer

VS Vijayarasan Sivanandham Syncfusion Team August 3, 2022 05:49 PM UTC

Hi Jakub Olichwier,

The reported problem occurs due to MappingName not being defined for the GridTemplateColumn. In this case, SfDataGrid does not identify the column from which the cell is copied. This is the expected behavior of SfDataGrid.

However, you can resolve the reported problem by defining the MappingName with some name to identify the GridTemplateColumn. It is not necessary to define the name of a field in the data object. Please refer to the below code snippet.

XAML Code Snippet:

<!--here MappingName defined for identify the GridTemplateColumn-->

<syncfusion:GridTemplateColumn HeaderText="UPS" MappingName="CustomColumn" MinimumWidth="80" Width="80">

                    <syncfusion:GridTemplateColumn.CellTemplate>

                        <DataTemplate>

                            <StackPanel Orientation="Horizontal">

                                <TextBlock >

                                        <Run Text="" />

                                        <Run Text="{Binding UpsFamilly.Name}" />

                                        <Run Text="" />

                                        <Run Text="{Binding UpsUnit.UpsOutputConfiguration}" />

                                </TextBlock>

                            </StackPanel>

                        </DataTemplate>

                    </syncfusion:GridTemplateColumn.CellTemplate>

</syncfusion:GridTemplateColumn>

You are trying to display the two column values combined with a single GridTemplateColumn. SfDataGrid does not support copying and pasting multiple column values from a single column.

However, you can achieve this by customizing the default copy and paste behaviors by overriding the GridCutCopyPaste class and setting it to SfDataGrid.GridCopyPaste. Please refer to the below code snippet.

public class SfDataGridBehavior : Behavior<SfDataGrid>

{

        protected override void OnAttached()

        {

            base.OnAttached();

            //Customized Copy Paste Behavior assigned to SfDataGrid

            this.AssociatedObject.GridCopyPaste = new CustomCopyPaste(this.AssociatedObject);

        }

 

 

        protected override void OnDetaching()

        {

            base.OnDetaching();

        }

}

C# Code Snippet related to Customizing Copy Paste Behavior

public class CustomCopyPaste : GridCutCopyPaste

    {

        public CustomCopyPaste(SfDataGrid sfGrid) : base(sfGrid)

        {

 

        }

 

 

        protected override void CopyCell(object record, GridColumn column, ref StringBuilder text)

        {

            //CopyParticularCellValue

            if (this.dataGrid.View == null)

                return;

            if (column == null || text == null) return;

            object copyText = null;

 

 

            var isUnbound = (bool)column.GetType().GetProperty("IsUnbound", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(column);

            if (isUnbound)

            {

                var unboundValue = this.dataGrid.GetUnBoundCellValue(column, record);

                copyText = unboundValue != null ? unboundValue.ToString() : string.Empty;

            }

            else

            {

 

                if (this.dataGrid.GridCopyOption.HasFlag(GridCopyOption.IncludeFormat))

                {

                    //here customizes based on your scenario

                    //here identify the GridTemplateColumn using MappingName

                    if (column.MappingName == "CustomColumn")

                    {

                        //here customized based on your scenario

                        //here get the multiple column value by using underline data object

                        var nameUpsFamilly = this.dataGrid.View.GetPropertyAccessProvider().GetFormattedValue(record, "UpsFamilly.Name");

                        var upsOutputConfiguration = this.dataGrid.View.GetPropertyAccessProvider().GetFormattedValue(record, "UpsUnit.UpsOutputConfiguration");

                        //here combine the values based on your scenario

                        copyText = nameUpsFamilly + " " + upsOutputConfiguration;

                    }

                    else

                        copyText = this.dataGrid.View.GetPropertyAccessProvider().GetFormattedValue(record, column.MappingName);

                }

                else

                {

                    //here customizes based on your scenario

                    //here identify the GridTemplateColumn using MappingName

                    if (column.MappingName == "CustomColumn")

                    {

                        //here customized based on your scenario

                        //here get the multiple column value by using underline data object

                        var nameUpsFamilly = this.dataGrid.View.GetPropertyAccessProvider().GetValue(record, "UpsFamilly.Name");

                        var upsOutputConfiguration = this.dataGrid.View.GetPropertyAccessProvider().GetValue(record, "UpsUnit.UpsOutputConfiguration");

                        //here combine the values based on your scenario

                        copyText = nameUpsFamilly + " " + upsOutputConfiguration;

                    }

                    else

                        copyText = this.dataGrid.View.GetPropertyAccessProvider().GetValue(record, column.MappingName);

                }

            }

            var copyargs = this.RaiseCopyGridCellContentEvent(column, record, copyText);

            if (!copyargs.Handled)

            {               

                if (this.dataGrid.Columns[leftMostColumnIndex] != column || text.Length != 0)

                    text.Append('\t');

 

                text.Append(copyargs.ClipBoardValue);

            }

        }

 

        protected override void CopyCells(GridSelectedCellsCollection selectedCells, StringBuilder text)

        {

            base.CopyCells(selectedCells, text);

        }

}


UG Link:
https://help.syncfusion.com/wpf/datagrid/clipboard-operations#customizing-copy-paste-behavior-in-wpf-datagrid

KB Link: https://www.syncfusion.com/kb/9913/how-to-copy-active-cell-value-alone-when-row-selection-in-wpf-datagrid-sfdatagrid

Note: We have provided customization only for while copying cells from SfDataGrid. You need to implement customization for pasting cell value in SfDatGrid. For more information related to customization paste cells value in SfDataGrid , please refer to the below user guide documentation link.


UG Link: https://help.syncfusion.com/wpf/datagrid/clipboard-operations#paste-a-cell-into-many-cells-in-wpf-datagrid

https://help.syncfusion.com/wpf/datagrid/clipboard-operations#paste-a-record-into-many-rows-in-wpf-datagrid

Please find the sample in the attachment and let us know if you have any concerns about this.


Regards,

Vijayarasan S


Attachment: Sample_ee22b2b3.zip

Marked as answer

JO Jakub Olichwier August 5, 2022 12:31 PM UTC

Hi  Vijayarasan,

I combined in a code behind properties binded previously to <Run> statements into one property. NOw there is no problem with standard column with MappingName. I think this is the easiest way.

I will also try the solution you provided.

Regards

Jakub



VS Vijayarasan Sivanandham Syncfusion Team August 5, 2022 12:42 PM UTC

Hi Jakub Olichwier,

We are glad to know that the reported problem has been resolved at your end. Please let us know if you have any further queries on this. We are happy to help you😊.

Regards,

Vijayarasan S


Loader.
Up arrow icon