在C#中更改文本框中的插入符号(光标)

4
我想要在C#的文本框中更改插入符号的样式,使其看起来更宽,就像旧的DOS应用程序中一样。
我有以下样式:enter image description here 我想要的样式如下:enter image description here 我尝试过:
using System.Runtime.InteropServices;

...

  [DllImport("user32.dll")]
  static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);
  [DllImport("user32.dll")]
  static extern bool ShowCaret(IntPtr hWnd);

...

public partial class Form1 : Form
{
    [DllImport("user32.dll")]
    static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);
    [DllImport("user32.dll")]
    static extern bool ShowCaret(IntPtr hWnd);

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Shown(object sender, EventArgs e)
    {
        CreateCaret(textBox1.Handle, IntPtr.Zero, 20, textBox1.Height);
        ShowCaret(textBox1.Handle);
    }
}

但是它看起来还是一样的。任何帮助都将不胜感激。提前感谢!
编辑:
这只是一个例子。我的真实代码如下:
TextBox textbox = new TextBox();
 textbox.MaxLength = fieldLength;
 textbox.Width = fieldLength*24;
 textbox.MaxLength = maxChars;
 this.Controls.Add(textbox);

 CreateCaret(textbox.Handle, IntPtr.Zero, 20, textbox.Height);
 ShowCaret(textbox.Handle);

代码被调用了,但没有改变任何东西。
编辑2:
我尝试了这个例子,它可以正常工作,但我的问题仍然存在: 在创建文本框时无法更改插入符号的位置。只有在使用表单创建文本框时才可以更改。

1
如果有人在阅读这篇文章:我的问题的答案是我在表单完全加载之前调用了方法。 - Jonas
2个回答

3
您没有正确链接事件,请更改为:

public partial class Form1 : Form
{
    [DllImport("user32.dll")]
    static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);
    [DllImport("user32.dll")]
    static extern bool ShowCaret(IntPtr hWnd);

    public Form1()
    {
        InitializeComponent();
        this.Shown += Form1_Shown;
    }

    private void Form1_Shown(object sender, EventArgs e)
    {
        CreateCaret(textBox1.Handle, IntPtr.Zero, 20, textBox1.Height);
        ShowCaret(textBox1.Handle);
    }
}

当在设计器的属性网格中双击 Shown 事件时,事件处理程序会附加在 .designer.cs 中,因此不会显示出来。但在这种情况下,您可能是正确的,因为原始代码似乎使用了正确附加的处理程序而且正常工作。我只是添加它,因为它可能并不那么明显。 - Jens
事件处理程序通常附加在表单 designer.cs 文件中的 InitializeComponent 方法内。编辑就像 Jens 1 分钟前说的那样 :) - Dbuggy
我的上面的代码只是一个例子。我在编程创建文本框时调用这两个方法。我只是想展示我使用了什么。这个方法被执行了,但是没有影响外观。 - Jonas
我尝试了你的例子,它运行得很好。如果我稍后创建一个文本框,这样做是否可能? - Jonas
@JonasSchafft 没问题,只需在需要的地方放置行 this.Shown += Form1_Shown; 即可。 - Thomas Ayoub
我猜你的答案是正确的,并向我展示了解决问题的方向。谢谢。 - Jonas

0

发生的情况似乎是所示事件仅在最初起作用。当您通过切换并返回控件来离开文本框时,插入符号将被底层代码重置。

请查看this线程中的答案。

我采用了他们的DrawDaret方法并进行了一些更改。在textbox1.Enter事件上调用DrawCaret不起作用。可能是textbox实现会通知Enter事件,然后更改插入符号。这将撤消在Enter事件处理程序中对插入符号所做的更改。

编辑

但是该控件还具有可以使用的GotFocus事件。

public partial class Form1 : Form
{
    [DllImport("user32.dll")]
    static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);
    [DllImport("user32.dll")]
    static extern bool ShowCaret(IntPtr hWnd);

    public Form1()
    {
        InitializeComponent();

        textBox1.GotFocus += new EventHandler(textBox1_GotFocus);
    }

    void textBox1_GotFocus(object sender, EventArgs e)
    {
        DrawCaret(textBox1);
    }

    public void DrawCaret(Control ctrl)
    {
        var nHeight = 0;
        var nWidth = 10;

        nHeight = Font.Height;

        CreateCaret(ctrl.Handle, IntPtr.Zero, nWidth, nHeight);
        ShowCaret(ctrl.Handle);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接