Вставить элемент управления в другой элемент управления в определенном месте? - PullRequest
0 голосов
/ 20 сентября 2018

Я работаю с выигрышными формами.У меня есть две формы: моя основная форма, 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 для размещения и изменения размера.когда он у вас есть, где вы хотите и насколько вы хотите большой, вы нажимаете кнопку, и он заменяет себя обычным текстовым полем такого размера в этой позиции.

Что я хочу, чтобы он делал: в настоящее время этоработает с одним исключением.Я добавляю его к элементам управления, tb_Main (мое основное текстовое поле, оно занимает всю форму) в Form1, он появляется.это правильный размер, за исключением случаев, когда я заполняю tb_Main текстом и прокручиваю, новое текстовое поле остается там, где оно находится, в то время как его родитель прокручивает за ним.

Вопрос: прокручиваю ли я вниз в свой документ и решаю ли я, что хочуздесь это текстовое поле, как мне обеспечить его положение относительно прокрутки текстового поля, в которое я его вставляю?tb_Main).

1 Ответ

0 голосов

Лучше создать richtextbox вместо textbox.Он имеет все возможности textbox и многое другое.Этот пример работает только с richtextbox.

в подклассе 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 );
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...