Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
235
UltraGrid's Default Copy to Clipboard truncates decimals
posted

I have a derived grid that has number formatting applied to the columns to prevent them from showing decimal places.

I set the grid to do its default Copying:

base.DisplayLayout.Override.AllowMultiCellOperations = AllowMultiCellOperation.CopyWithHeaders;

When it copies to the clipboard, it copies as text exactly what is displayed in the grid, which means it truncates the decimals (just like I do in the grid).  However, since the grid knows what the full value is, i would like the copy behavior to essentially copy the data in a manner to not lose any of the decimal places when I paste the data elsewhere.

How can I do this?  Thank you. 

Parents
  • 469350
    Suggested Answer
    Offline posted

    Hi Robert,

    The grid (usually) copies what the user sees. It would probably be confusing for a user to copy from the grid and paste it only to find that what he pasted doesn't match what he copied.

    I took a look at the code to see if I could find a solution for you, and it looks like what the grid does is it fires the BeforeMultiCellOperation, which gives you a chance to change the values being written to the clipboard. But it applies to Formatting to the values immediately after the event fires and there's no way to prevent it.

    So there are two ways you can achieve what you want.

    Method 1:

    Change the value that is being sent to the clipboard to a string representation of the value. The string data type doesn't support any formatting. So if you change the value to a string, you will get what you put in.


            private void ultraGrid1_BeforeMultiCellOperation(object sender, BeforeMultiCellOperationEventArgs e)
            {            
                if (e.Operation == MultiCellOperation.Copy)
                {
                    foreach (UltraGridCell cell in e.Cells)
                    {
                        if (cell.Column.Key == "Decimal 1")
                        {                        
                            e.NewValues[cell].Value = cell.Value.ToString();
                        }
                    }
                }
            }

    Method 2

    Temporarily remove the formatting from the column while the copy operation is occurring.


            string cachedFormat = null;
            private void ultraGrid1_BeforeMultiCellOperation(object sender, BeforeMultiCellOperationEventArgs e)
            {            
                if (e.Operation == MultiCellOperation.Copy)
                {
                    foreach (UltraGridCell cell in e.Cells)
                    {
                        if (cell.Column.Key == "Decimal 1")
                        {
                            this.cachedFormat = cell.Column.Format;
                            cell.Column.ResetFormat();
                        }
                    }
                }
            }

            private void ultraGrid1_AfterPerformAction(object sender, AfterUltraGridPerformActionEventArgs e)
            {
                UltraGrid grid = (UltraGrid)sender;

                if (cachedFormat != null &&
                    e.UltraGridAction == UltraGridAction.Copy)
                {
                    grid.DisplayLayout.Bands[0].Columns["Decimal 1"].Format = this.cachedFormat;
                    this.cachedFormat = null;
                }
            }

    I just threw this code together quickly, so its assuming that there is only one column that you need to deal with here. If you have more than one, then it would probably be wise to create a better caching structure that holds the formats for each column and keys them on the column object itself in a dictionary.

    The advantage of Method 1 is that it's much easier to implement. The down side is that if you are copying to Excel, you will end up copying a numeric value as a string. Excel will give you a warning and you won't be able to use the value in a formula, since it will be a string.

    Method 2 maintains the numeric value, but it's more code and also I'm not thrilled about the idea of changing the format of the column dynamically like this. It's probably not very efficient and there's a risk that there might be a case where BeforeMultiCellOperation fires and AfterPerformAction doesn't and then you could end up losing the formatting on the on-screen grid.

Reply Children