重写 DataGridViewCell.GetClipboardContent - 我应该支持(重新实现)格式细节吗?

发布于 2024-12-03 11:23:57 字数 826 浏览 0 评论 0原文

我的一些 DataGridViewCells 在其 GetClipboardContent 方法中返回错误的值。它们是 DataGridViewComboBoxColumn 单元格中的单元格,因此它们使用单​​元格的 displayed 属性,而不是 value 属性。我希望它返回值本身。

最初的尝试只是

  Protected Overrides Function GetClipboardContent(ByVal rowIndex As Integer, ByVal firstCell As Boolean, ByVal lastCell As Boolean, ByVal inFirstRow As Boolean, ByVal inLastRow As Boolean, ByVal format As String) As Object
    Return Value
  End Function

在我的 DataGridViewComboBoxCell 后代中使用,但后来我注意到每个单元格值调用此方法多次,对于 DataGridView 标准支持的每种数据格式调用一次,即 format="HTML ”、“文本”、“UnicodeText”和“Csv”。

对于 csv,如果不是最后一个单元格,基本实现会附加一个逗号;对于 html,它会添加正确的标签,具体取决于它是否是表/表行中的第一/最后一行/单元格等。我认为这种格式特定于,不特定于单元格值。

那么,我如何替换最终出现在剪贴板中的而不重新实现所有这些特定于格式的方面?这将导致相当多的代码用于已经存在的功能在基类中,不是吗?

Some of my DataGridViewCells return the wrong value in their GetClipboardContent method. They are cells in a DataGridViewComboBoxColumn cells, so they use the displayed property, not the value property of the cell. I want it to return the value itself.

An initial attempt was simply using

  Protected Overrides Function GetClipboardContent(ByVal rowIndex As Integer, ByVal firstCell As Boolean, ByVal lastCell As Boolean, ByVal inFirstRow As Boolean, ByVal inLastRow As Boolean, ByVal format As String) As Object
    Return Value
  End Function

in my DataGridViewComboBoxCell descendant but then I noted that this method is called more than one time per cell value, once for every data format DataGridView supports by standard, which are format="HTML", "Text", "UnicodeText" and "Csv".

For csv, the base implementation appends a comma if it's not the last cell, for html it adds the correct tags depending on if it's the first/last row/cell in the table/table row, etc. I consider this format-specific, not cell-value specific.

So how could I replace the value that ends up in the clipboard without re-implementing all those format-specific aspects? That would result in quite some code for functionality that already exists in the base class, wouldn't it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哎呦我呸! 2024-12-10 11:23:57

简短回答:处理CellFormatting,如果在剪贴板“值获取”期间请求格式化,则返回未格式化的值而不是显示值。为了能够检测到这一点,让组合框列创建一个组合框单元格子代,当调用其 GetClipboardContent 方法时,该子代会在列的属性中设置一个标志。

长答案:

嗯,似乎基本方法做了类似的事情(来自 Mono 的 c# 代码,来自 http://www.eg.bucknell.edu/~cs208/subpages/software/src/mono-2.6.7/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewCell .cs):

    protected virtual object GetClipboardContent (int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) {
            if (DataGridView == null)
            return null;

        if (rowIndex < 0 || rowIndex >= DataGridView.RowCount)
            throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");

        string value = null;

        if (Selected) {
            DataGridViewCellStyle style = GetInheritedStyle (null, rowIndex, false);
            value = GetEditedFormattedValue (rowIndex, DataGridViewDataErrorContexts.ClipboardContent | DataGridViewDataErrorContexts.Formatting) as string;
        }

        if (value == null)
            value = string.Empty;

        string table_prefix = string.Empty, cell_prefix = string.Empty, row_prefix = string.Empty;
        string table_suffix = string.Empty, cell_suffix = string.Empty, row_suffix = string.Empty;

        if (format == DataFormats.UnicodeText || format == DataFormats.Text) {
            if (lastCell && !inLastRow)
                cell_suffix = Environment.NewLine;
            else if (!lastCell)
                cell_suffix = "\t";
        } else if (format == DataFormats.CommaSeparatedValue) {
            if (lastCell && !inLastRow)
                cell_suffix = Environment.NewLine;
            else if (!lastCell)
                cell_suffix = ",";
        } else if (format == DataFormats.Html) {
            if (inFirstRow && firstCell)
                table_prefix = "<TABLE>";
            if (inLastRow && lastCell)
                table_suffix = "</TABLE>";
            if (firstCell)
                row_prefix = "<TR>";
            if (lastCell)
                row_suffix = "</TR>";
            cell_prefix = "<TD>";
            cell_suffix = "</TD>";

            if (!Selected) {
                value = " ";
            }
        } else {
            return value;
        }

        value = table_prefix + row_prefix + cell_prefix + value + cell_suffix + row_suffix + table_suffix;

        return value;
    }

这让我相信我应该重写 GetEditedFormattedValue 并检查在中设置的 ClipboardContentContext 参数,允许我检测它是否正在获取剪贴板的值,如果是,则返回 ComboBox 单元格后代的值,而不是 DisplayValue。

不过,GetEditedFormattedValue 无法被覆盖。

因此,我被迫在列中创建一个标志,如果单元格的 GetClipboardContent 正在运行,则设置它,并在网格的 CellFormatting 事件中返回单元格的未格式化值(如果标志已设置。

工作正常。

Short answer: Handle CellFormatting, and if formatting is requested during a clipboard "value fetch", return the unformatted value instead of the display value. To be able to detect this, let the combobox column create a combobox cell descendant which sets a flag in the column's properties when its GetClipboardContent method is called.

Long answer:

Mh, it seems the base method does something like this (c# code from Mono from http://www.eg.bucknell.edu/~cs208/subpages/software/src/mono-2.6.7/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewCell.cs):

    protected virtual object GetClipboardContent (int rowIndex, bool firstCell, bool lastCell, bool inFirstRow, bool inLastRow, string format) {
            if (DataGridView == null)
            return null;

        if (rowIndex < 0 || rowIndex >= DataGridView.RowCount)
            throw new ArgumentOutOfRangeException ("rowIndex", "Specified argument was out of the range of valid values.");

        string value = null;

        if (Selected) {
            DataGridViewCellStyle style = GetInheritedStyle (null, rowIndex, false);
            value = GetEditedFormattedValue (rowIndex, DataGridViewDataErrorContexts.ClipboardContent | DataGridViewDataErrorContexts.Formatting) as string;
        }

        if (value == null)
            value = string.Empty;

        string table_prefix = string.Empty, cell_prefix = string.Empty, row_prefix = string.Empty;
        string table_suffix = string.Empty, cell_suffix = string.Empty, row_suffix = string.Empty;

        if (format == DataFormats.UnicodeText || format == DataFormats.Text) {
            if (lastCell && !inLastRow)
                cell_suffix = Environment.NewLine;
            else if (!lastCell)
                cell_suffix = "\t";
        } else if (format == DataFormats.CommaSeparatedValue) {
            if (lastCell && !inLastRow)
                cell_suffix = Environment.NewLine;
            else if (!lastCell)
                cell_suffix = ",";
        } else if (format == DataFormats.Html) {
            if (inFirstRow && firstCell)
                table_prefix = "<TABLE>";
            if (inLastRow && lastCell)
                table_suffix = "</TABLE>";
            if (firstCell)
                row_prefix = "<TR>";
            if (lastCell)
                row_suffix = "</TR>";
            cell_prefix = "<TD>";
            cell_suffix = "</TD>";

            if (!Selected) {
                value = " ";
            }
        } else {
            return value;
        }

        value = table_prefix + row_prefix + cell_prefix + value + cell_suffix + row_suffix + table_suffix;

        return value;
    }

That lets me believe that I should override GetEditedFormattedValue and check for the ClipboardContent bit being set in the Context argument, allowing me to detect if it is fetching the value for the clipboard, and if so, return the Value of the ComboBox cell descendant, not the DisplayValue.

GetEditedFormattedValue cannot be overriden, though.

So i am forced to create a flag in the column, set it if the cell's GetClipboardContent is running, and return the unformatted value of the cell in the Grid's CellFormatting event if the flag is set.

Works fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文