我正在使用获胜表格。我有两种形式:我的主要形式Form1
和我制作的名为TextBlock
的形式。我正在制作一个文本编辑器,您可以在其中将文本框放在页面周围,然后进行编辑(想一想)。
这是我的两种形式。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
saveFileDialog.Filter = "Text File|*.txt";
var result = saveFileDialog.ShowDialog();
if (result == DialogResult.OK)
{
StreamWriter writer = new
StreamWriter(saveFileDialog.OpenFile());
writer.Write(tb_Main.Text);
writer.Dispose();
writer.Close();
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void button_tb_Click(object sender, EventArgs e)
{
TextBlock tb_edit = new TextBlock();
tb_edit.Text = "New Text Block";
// tb_edit.Multiline = true;
// tb_edit.Size = new Size(100,100);
// tb_edit.MinimumSize = new Size(50, 50);
tb_edit.form1 = this;
tb_edit.TopLevel = false;
tb_edit.btn_accepttb.BringToFront();
tb_Main.Controls.Add(tb_edit);
tb_edit.Show();
tb_edit.BringToFront();
}
}
和我的自定义表单:
public partial class TextBlock : Form
{
public Form1 form1;
public TextBlock()
{
InitializeComponent();
}
private void btn_accepttb_Click(object sender, EventArgs e)
{
TextBox tb_edit = new TextBox();
tb_edit.Text = "New Text Block";
tb_edit.Multiline = true;
tb_edit.Size = this.Size;
int dif = form1.tb_Main.Lines.Count()*(int)tb_edit.Font.Size;
Point loca = new Point(this.Location.X,this.Location.Y+dif);
tb_edit.Location = this.Location;
form1.tb_Main.Controls.Add(tb_edit);
tb_edit.Show();
tb_edit.BringToFront();
form1.tb_Main.Controls.Remove(this);
}
}
它的作用:它可以复制我的TextBlock,以用于放置和调整大小。当您将其放置在所需的位置以及所需的大小时,请单击该按钮,然后将其替换为该位置在该位置的常规文本框。
我要它做什么:当前它正在工作,只有一个异常。我将其添加到Form1中tb_Main的控件中(我的主文本框,它占据了整个表单),它显示了出来。它的大小正确,除非当我用文本填充tb_Main并滚动时,新的文本框保持在原位置,而其父级滚动到其后。
问题:如果我向下滚动到文档中并决定要在此处放置此文本框,如何确保将其相对于放置的文本框的滚动位置。因此,当我滚动时,它基本上保持嵌入在我放置它的页面(当我说“页面”是指我的tb_Main时)。
答案 0 :(得分:1)
最好创建一个richtextbox
而不是textbox
。它具有textbox
的所有功能以及更多功能。此示例仅对richtextbox
使用{strong> 。
子类richtextbox
:
class MyRichTextBox : RichTextBox {
[DllImport( "user32.dll" )]
private static extern bool GetScrollInfo( IntPtr hwnd, SBOrientation fnBar,
ref SCROLLINFO lpsi );
[StructLayout( LayoutKind.Sequential )]
private struct SCROLLINFO {
public uint cbSize;
public ScrollInfoMask fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}
private enum ScrollInfoMask : uint {
SIF_RANGE = 0x1,
SIF_PAGE = 0x2,
SIF_POS = 0x4,
SIF_DISABLENOSCROLL = 0x8,
SIF_TRACKPOS = 0x10,
SIF_ALL = ( SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS ),
}
private enum SBOrientation : int {
SB_HORZ = 0x0,
SB_VERT = 0x1,
}
private const int WM_VSCROLL = 0x115;
private const int SB_LINEUP = 0;
private const int SB_LINEDOWN = 1;
private const int SB_PAGEUP = 2;
private const int SB_PAGEDOWN = 3;
private const int SB_THUMBPOSITION = 4;
private const int SB_THUMBTRACK = 5;
private const int SB_TOP = 6;
private const int SB_BOTTOM = 7;
private const int SB_ENDSCROLL = 8;
private bool isThumbTrack = false;
private TextBox childTextbox = null;
private int scrollPos = 0;
public MyTextBox( TextBox textbox ) { //here you pass the child textbox you want to scroll
childTextbox = textbox;
}
protected override void OnVScroll( EventArgs e ) {
if( childTextbox == null ) { base.OnVScroll( e ); return; }
SCROLLINFO si = new SCROLLINFO();
si.cbSize = (uint)Marshal.SizeOf( si );
si.fMask = ScrollInfoMask.SIF_ALL;
GetScrollInfo( this.Handle, SBOrientation.SB_VERT, ref si );
//there is a difference when the user uses the thumb to get scroll pos.
//When user uses the thumb we get *nTrackPos* otherwise *nPos*
if( isThumbTrack == true ) {
childTextbox.Location = new Point( childTextbox.Location.X, childTextbox.Location.Y -
(si.nTrackPos - scrollPos ) );
isThumbTrack = false;
scrollPos = si.nTrackPos;
}
else {
childTextbox.Location = new Point( childTextbox.Location.X, childTextbox.Location.Y -
( si.nPos - scrollPos ) );
scrollPos = si.nPos;
}
base.OnVScroll( e );
}
protected override void WndProc( ref Message m ) {
int wParam;
if(m.Msg == WM_VSCROLL ) {
wParam = m.WParam.ToInt32();
wParam &= 0xFFFF; //get low 16 bits of wParam
//Check if user is using the thumb to scroll
if( wParam == SB_THUMBTRACK ) {
isThumbTrack = true;
}
}
base.WndProc( ref m );
}
}