2016-09-09 2 views
2

Я пытаюсь создать маскированное текстовое поле с цветами границ.Как нарисовать границу для MaskedTextBox с использованием пользовательского цвета?

Я попробовал этот код, приведенный ниже, чтобы достичь этого:

public class MaskedTextBoxWithBorder : UserControl 
{ 
    MaskedTextBox maskedtextBox; 

    public MaskedTextBoxWithBorder() 
    { 
     maskedtextBox = new MaskedTextBox() 
     { 
      BorderStyle = BorderStyle.FixedSingle, 
      Location = new Point(-1, -1), 
      Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right 
     }; 
     Control container = new ContainerControl() 
     { 
      Dock = DockStyle.Fill, 
      Padding = new Padding(-1) 
     }; 
     container.Controls.Add(maskedtextBox); 
     this.Controls.Add(container); 

     DefaultBorderColor = SystemColors.ControlDark; 
     FocusedBorderColor = Color.Red; 
     BackColor = DefaultBorderColor; 
     Padding = new Padding(1); 
     Size = maskedtextBox.Size; 
    } 

    public Color DefaultBorderColor { get; set; } 
    public Color FocusedBorderColor { get; set; } 

    public override string Text 
    { 
     get 
     { 
      return maskedtextBox.Text; 
     } 
     set 
     { 
      maskedtextBox.Text = value; 
     } 
    } 

    protected override void OnEnter(EventArgs e) 
    { 
     BackColor = FocusedBorderColor; 
     base.OnEnter(e); 
    } 

    protected override void OnLeave(EventArgs e) 
    { 
     BackColor = DefaultBorderColor; 
     base.OnLeave(e); 
    } 

    protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) 
    { 
     base.SetBoundsCore(x, y, width, maskedtextBox.PreferredHeight, specified); 
    } 
} 

Но проблема в том, что не имеет все возможности замаскированной текстовое поле, как установка типа маски и т.д.

Так что я изменил мой код:

public class MaskedTextBoxWithBorder : UserControl 

Теперь у меня есть все функции текстового поля Masked, но цвета границы не влияют.

Есть ли способ расширить текстовое поле Masked, чтобы получить стиль границы без потери функций, подобных этому, что невозможно.

public class MaskedTextBoxWithBorder : UserControl, MaskedTestBox 
+0

Вам не нужно, что контроль контейнера. UserControl уже является элементом управления контейнером. – LarsTech

ответ

2

Чтобы нарисовать границу MaskedTextBox вы должны переопределить WndProc и обрабатывать WM_NCPAINT сообщений. Затем получите окно dc элемента управления и создайте объект Graphics из этого постоянного тока, затем нарисуйте границу для элемента управления. Это решение было также использовано в ToolStripTextBox. Решение можно применять также на TextBox.

using System; 
using System.Drawing; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
public class MyMaskedTextBox : MaskedTextBox 
{ 
    public const int WM_NCPAINT = 0x85; 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetWindowDC(IntPtr hWnd); 
    [DllImport("user32.dll")] 
    public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); 
    protected override void WndProc(ref Message m) 
    { 
     base.WndProc(ref m); 
     if (m.Msg == WM_NCPAINT) 
     { 
      var hdc = GetWindowDC(this.Handle); 
      using (var g = Graphics.FromHdcInternal(hdc)) 
      { 
       g.DrawRectangle(Pens.Blue, new Rectangle(0, 0, Width - 1, Height - 1)); 
      } 
      ReleaseDC(this.Handle, hdc); 
     } 
    } 
} 
+0

Также, чтобы увидеть, как изменить сфокусированный цвет границы, посмотрите [этот пост] (http://stackoverflow.com/a/38405319/3110834) –

+0

Также [здесь] (http: // stackoverflow.com/a/39420512/3110834) является примером того, как добавить свойство 'BorderColor' для' TextBox'. –

+0

Кажется, сообщение отвечает на ваш вопрос, и было бы здорово, если бы вы приняли ответ. В противном случае сообщите мне, если у вас возникнут проблемы с применением ответа. Также убедитесь, что вы смотрите на [связанный пост] (http://stackoverflow.com/a/39420512/3110834), который содержит полную реализацию свойства 'BorderColor'. –

2

TextBox и управление MaskedTextBox только обертки Win32 TextBox управляет таким владелец вовлекая их (для пользовательских границ, накладок или что-либо еще) является немного более сложным, чем обычно. Вот что вы должны сделать, чтобы достичь того, что вы пытаетесь сделать.

  1. Выведите из MaskedTextBox: public class MaskedTextBoxWithBorder : MaskedTextBox
  2. Получить доступ к потоку сообщений для Win32 TextBox (он рисует себя в ответ на несколько сообщений, так что вам нужно, чтобы поймать их всех, а не только стандартные WM_PAINT сообщений).
  3. Получить дескриптор контекста устройства и преобразовать его в управляемый объект Graphics, чтобы нарисовать границу.

Взгляните на следующей статье, которая объясняет каждый шаг в деталях: Adding an Icon or Control to a TextBox or ComboBox

Даже если в статье рассматриваются основные управления TextBox, это не имеет значения. Оба TextBox и MaskedTextBox вытекают из TextBoxBase класса, который реализует все важные детали мы заинтересованы.

+0

Граница оформляется в неклиентской области, и единственным сообщением, которое нужно обработать для рисования границы с пользовательским цветом, является 'WM_NCPAINT'. –

0

Ну, как правило, в данном приложении, можно изменить только несколько собственности, поэтому вы можете просто добавить некоторые дополнительные свойства для элемента управления пользователя для тех свойств, которые вы хотите быть в состоянии изменить.

public class MaskedTextBoxWithBorder : UserControl 
{ 
    MaskedTextBox maskedtextBox; 

    // Other existing code... 

    public string Mask 
    { 
     get { return maskedtextBox.Mask; } 
     set { maskedtextBox.Mask = value; } 
    } 

    // Do same thing for other properties you want to change... 
} 

Если вы действительно хотите изменить много свойств, то другие решения могут быть более подходящим ...

Смежные вопросы