【问题标题】:Catch text before it's pasted into textview在将文本粘贴到 textview 之前捕获文本
【发布时间】:2010-12-15 14:07:52
【问题描述】:

我有一个文本视图,当从剪贴板将某些内容粘贴到其中时,我需要截取该文本并对其进行一些预处理,然后才能将其放入文本视图中。

我已尝试收听“PasteClipboard”事件,但它无法让我修改传入的文本。和“textview.Buffer.Changed”事件,它在粘贴的文本进入文本视图后触发。

提前致谢。

【问题讨论】:

  • 那么如果你使用Buffer.Changed,你真的看到修改前的文本在你的修改版本出现之前就闪现了吗?
  • 很遗憾没有,当 buffer.changed 被触发时,我试图捕捉的文本已经被放入文本缓冲区。

标签: c# linux mono gtk gtk#


【解决方案1】:

AFAIK 您最好的选择是在插入文本后对其进行后处理 - TextBuffer 上的 InsertText 事件具有告诉您插入文本的位置和大小的参数,因此您可以删除、处理和重新插入它。您当然希望避免捕获 1 字符插入(击键)和您自己的重新插入,但这很简单。

我能想到的唯一其他选择是通过捕获粘贴键命令、中键单击等重新实现粘贴支持 - 但请注意,命令键可以在用户的​​ gtkrc 文件中被覆盖,因此实现这正确地可能会变得多毛。

在 irc.gnome.org 上的#gtk+ IRC 频道中询问可能也是值得的。

【讨论】:

  • GTK中有没有类似WndProc的东西?我已经有几年没有使用 Mono 了,我承认,我对这个框架有点生疏了。
  • 我不知道,不。它一直是基于事件的(C 中的“信号”)。 Windows/X/Carbon 消息系统被 GDK 平台抽象隐藏。
  • 当然,即使有,你也需要一个等效的“WM_PASTE”,TBH 是这里的问题。
  • 也就是说……通常在这种情况下,内置行为由小部件本身添加的信号处理程序处理。因此,要抢占内置行为,您可以将 [GLib.ConnectBefore] 放在信号处理程序上,使其在 内置处理程序之前连接,然后可选择将 arg.RetVal 设置为 true if您想阻止信号传播到小部件的处理程序。但是,这仅在 EventArgs 是 SignalArgs 的子类时才有效,此处似乎并非如此。
【解决方案2】:

做了一些简短的谷歌搜索,我在Gtk.TextBuffer GTK alternative to .net WndProc in Mono 上找到了以下文档。看来您可能希望将 [GLib.ConnectBefore] 属性添加到代码中以访问 GTK 的 WndProc 方法。上面 Beaner 的代码对 GTK 框架稍作修改可能就可以工作。

【讨论】:

  • GTK 中没有直接等效的 WndProc。
【解决方案3】:

这可能对您没有帮助,但我在实现 TextBox 的自定义控件中捕获了 WM_PASTE 消息。我将 GetText 从剪贴板获取到一个字符串变量中,如果它与我要查找的内容匹配,我对变量进行更改并将 .Text 设置为我的变量并吞下事件,以便文本框获取它。如果这不是我想要的,但允许我只是通过 base.WndProc(ref m) 传递事件。

示例:

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_PASTE)
    {
        string clipboardVin = Clipboard.GetText();
        string newVin = "";
        if (SelectionLength > 0)
        {
            newVin = Text.Replace(SelectedText, "");
        }
        else
        {
            newVin = Text;
        }
        newVin = newVin.Insert(SelectionStart, clipboardVin);
        if (!vinRegEx.IsMatch(newVin))
        {
            m.Result = new IntPtr(Convert.ToInt32(true));
            MessageBox.Show("The resulting text is not a valid VIN.", "Can Not Paste", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        else
        {
            base.WndProc(ref m);
        }
    }
    else
    {
        base.WndProc(ref m);
    }
}

【讨论】:

  • 不幸的是,这对我没有帮助。我正在尝试在 gtk 下的 linux 上执行此操作。
  • 这个问题应该去掉c#标签吗?
  • 不,它是 C#。 GTK# 是跨平台 GTK+ 工具包的 .NET/Mono 包装器,就像 System.Windows.Forms 是 Win32 GUI 的包装器。
猜你喜欢
  • 1970-01-01
  • 2018-11-14
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 2021-06-19
  • 1970-01-01
相关资源
最近更新 更多