簡體   English   中英

構造函數中的C#set屬性未按預期順序

[英]C# set property in constructor not vork as expected

我嘗試使用帶有水印的文本框

public partial class ModernBox : Form
{
    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HT_CAPTION = 0x2;

    [DllImportAttribute("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    [DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();

    private const int WM_NCHITTEST = 0x84;
    private const int HTCLIENT = 0x1;
    private const int HTCAPTION = 0x2;

    static Color ColorMain = Color.FromArgb(42, 42, 44);
    static Color ColorTransparent = Color.Transparent;

    Panel p_bro = new Panel{Visible = false};
    Panel p_auth = new Panel{Visible = false};
    WaterMarkTextBox textBox1;// = new WaterMarkTextBox{Location = new Point(10,40),Visible = true,Width = 200};
    WaterMarkTextBox textBox2 = new WaterMarkTextBox{

    Location = new Point(10,70),Visible = true,Width = 200,WaterMark = "123"};

    protected override void WndProc(ref Message message)
    {
        base.WndProc(ref message);

        if (message.Msg == WM_NCHITTEST && (int)message.Result == HTCLIENT)
            message.Result = (IntPtr)HTCAPTION;
    }

    public ModernBox()
    {
      InitializeComponent();

      panel1.MouseMove += (o, e) => {
                if (e.Button == MouseButtons.Left) {
                    ReleaseCapture();
                    SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
                }
            };

      panel1.BackColor = ColorMain;

      this.StartPosition = FormStartPosition.CenterScreen;
      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
      this.Width = 600;
      this.Height = 400;

      p_bro.Controls.Add(Program.presentation.webBrowser1); 
      Program.presentation.webBrowser1.Location = new Point(10,-70);
      Program.presentation.webBrowser1.Height = 560;
      p_bro.Location = new Point(0,30);

      //this.Focus();
      this.textBox1 = new WaterMarkTextBox{Location = new Point(10,40),Visible = true,Width = 400,WaterMark = "mark",Tip = "tip"};
      this.textBox1.PerformLayout();
      //textBox1.WaterMark = "wm1";
      //textBox1.Tip = "tip1";

      this.Controls.Add(p_bro); 
      this.Controls.Add(p_auth);
      this.Controls.Add(this.textBox1);
      this.Controls.Add( textBox2);

      //ModeAuth();
      //ModeBro();
    }

    public void ModeBro()
    {
        p_auth.Hide();
        p_bro.Show();

        Program.presentation.webBrowser1.BringToFront();

        p_bro.MouseHover += (o, e) => { Program.presentation.webBrowser1.Focus(); };
        p_bro.AutoScroll = false;
        p_bro.HorizontalScroll.Enabled = false;
        p_bro.HorizontalScroll.Visible = false;
        p_bro.Width = Program.presentation.webBrowser1.Width;
        p_bro.Height = Program.presentation.webBrowser1.Height-50;

        this.Width = p_bro.Width;//Program.presentation.webBrowser1.Width; 
        this.Height = p_bro.Height-5;//Program.presentation.webBrowser1.Height-20;
    }

    public void ModeAuth()
    {
        p_bro.Hide();
        p_auth.Show();

        this.Width = 600;
        this.Height = 400;
    }

    private void BtnClose_Click(object sender, EventArgs e)
    {
      this.Close();
    }

    private void BtnMaximize_Click(object sender, EventArgs e)
    {
      if(this.WindowState != FormWindowState.Minimized)
        this.WindowState = FormWindowState.Maximized;
      else 
        this.WindowState = FormWindowState.Normal;
    }

    private void BtnMinimaze_Click(object sender, EventArgs e)
    {
      this.WindowState = FormWindowState.Minimized;
    }
}

public class WaterMarkTextBox : TextBox
{
    ToolTip TTip = new ToolTip();

    private string _WaterMark;
    public string WaterMark
    {
        get { return _WaterMark; }
        set { _WaterMark = value; }
    }

    private string _Tip;
    public string Tip
    {
        get { return _Tip; }
        set { _Tip = value; }
    }

    public WaterMarkTextBox()
    {
        this.ForeColor = SystemColors.GrayText;
        //if(WaterMark==null) MessageBox.Show("fail");

        this.Text = _WaterMark;
        this.Leave += new System.EventHandler(this._Leave);
        this.Enter += new System.EventHandler(this._Enter);
        this.MouseHover += new EventHandler(WaterMarkTextBox_MouseHover);
    }

    private void _Leave(object sender, EventArgs e)
    {
        if (this.Text.Length == 0)
        {
            this.Text = _WaterMark;
            this.ForeColor = SystemColors.GrayText;
        }
    }

    private void _Enter(object sender, EventArgs e)
    {
        //MessageBox.Show(_WaterMark);
        if (this.Text == _WaterMark)
        {
            this.Text = "";
            this.ForeColor = SystemColors.WindowText;
        }
    }

    private void WaterMarkTextBox_MouseHover(object sender, EventArgs e)
    {
        if (Tip != null)
            TTip.Show(Tip, this, 0, (int)(this.Height * 1.2), 2000);
    }
}

如您所見,沒有出現水印,在構造函數中, WaterMarkTip值為NULL

在此處輸入圖片說明

但是點擊后它可以正常工作

在此處輸入圖片說明

我需要做什么來解決這個問題?

VS 2010

您正在將構造函數initializer混合使用。

this.textBox1 = new WaterMarkTextBox{Location = new Point(10,40),Visible = true,Width = 400,WaterMark = "mark",Tip = "tip"};

相當於這樣的東西

var temp = new WaterMarkTextBox();
temp.Location = new Point(10,40);
temp.Visible = true;
temp.Width = 400;
temp.WaterMark = "mark";
temp.Tip = "tip";
this.textBox1 = temp;

如您所見, Watermark屬性是在構造函數調用之后分配的(第一行)。 如果需要在構造函數中使用它,請使用參數來構造一個構造函數

public WaterMarkTextBox(string watermark)
{
    Watermark = watermark;
    // ...
}

或處理Watermark屬性設置器。

編輯:從您的評論,我看到您仍然不了解。 好的,所以您的原始代碼實際上是一個構造函數調用+屬性分配

this.textBox1 = new WaterMarkTextBox() {Location = new Point(10,40),Visible = true,Width = 400,WaterMark = "mark",Tip = "tip"};

請注意{之前的() -這是實際的構造函數調用,只是C#允許忽略它(但仍然存在)。 如果像建議的那樣更改構造函數,則該行將變為

this.textBox1 = new WaterMarkTextBox("mark") {Location = new Point(10,40),Visible = true,Width = 400,Tip = "tip"};

但是在編輯之前請注意我答案的最后一部分

或處理Watermark屬性設置器。

屬性設置器不僅用於設置后備字段。 您遇到的問題是由Watermark屬性設置器的錯誤實現引起的。 因此,ether將其設置為只讀(刪除setter)並將其值傳遞給構造函數,或者,如果確實需要將該值傳遞給構造函數,則保留無參數構造函數並正確實現setter。 像這樣

public class WaterMarkTextBox : TextBox
{
    ToolTip TTip = new ToolTip();

    private string _WaterMark = string.Empty;
    public string WaterMark
    {
        get { return _WaterMark; }
        set
        {
            if (value == null) value = string.Empty;
            if (_WaterMark == value) return;
            _WaterMark = value;
            if (this.DesignMode || this.ContainsFocus) return;
            this.Text = _WaterMark;
            this.ForeColor = SystemColors.GrayText;
        }
    }

    private string _Tip;
    public string Tip
    {
        get { return _Tip; }
        set { _Tip = value; }
    }

    public WaterMarkTextBox()
    {
        this.Leave += new System.EventHandler(this._Leave);
        this.Enter += new System.EventHandler(this._Enter);
        this.MouseHover += new EventHandler(WaterMarkTextBox_MouseHover);
    }

    private void _Leave(object sender, EventArgs e)
    {
        if (this.Text.Length == 0)
        {
            this.Text = _WaterMark;
            this.ForeColor = SystemColors.GrayText;
        }
    }

    private void _Enter(object sender, EventArgs e)
    {
        if (this.Text == _WaterMark)
        {
            this.Text = "";
            this.ForeColor = SystemColors.WindowText;
        }
    }

    private void WaterMarkTextBox_MouseHover(object sender, EventArgs e)
    {
        if (Tip != null)
            TTip.Show(Tip, this, 0, (int)(this.Height * 1.2), 2000);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM