2015-09-27 134 views
0

我尝试用水印C#设置属性

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

enter image description here

但它的工作原理点击

enter image description here后罚款。

我需要做些什么来解决这个问题?

VS 2010

回答

1

你是混合构造初始化。该生产线

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属性setter。

编辑:从你的评论我看你还是不明白。好了,你原来的代码实际上是一个构造函数调用+属性分配

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属性setter。

属性设定器不仅用于设置后台字段。您遇到的问题是由于您的Watermark属性设置器的错误实施引起的。因此,以太使它只读(移除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); 
    } 
} 
+0

但我想用这种方式 WaterMarkTextBox BTN =新WaterMarkTextBox使用它{提示=“myTip”,位置=新的点(30,30)} 我的意思是在一条作业线上进行原生属性位置和我的财产提示。可能吗? 如果即使它在构造函数之后调用,我的目标是看到文本,所以如果延迟将是秒,那并不重要。但在我的情况下,我不能看到文字,直到没有点击WaterTextBox1然后WaterTB2 –

+0

@NikitaShevchenko仔细阅读原始答案,然后更新。 –