TextBox Designe

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von Facebamm.

    TextBox Designe

    Hallo,

    ist es möglich das komplett Designe einer TextBox zu ändern?
    Warum ich das frage? Ich hab jetzt kanpp 4h veruscht die TextBoxBase auf mein Control zu programmieren damit ich die Mechanik des Textschreibens bekomme, aber ohne erfolg.

    Nun dachte ich okey, evtl. mit C++ aber dort ist in den Videos das gleiche Spiel. Alle TextBoxen sehen Grau und Viereckig aus -.-

    Wie es Momentan aussieht bei mir

    Spoiler anzeigen

    Mein Code bis Jetzt

    C#-Quellcode

    1. class CueTextBox : Control {
    2. /*
    3. * Text
    4. * Courser
    5. * KeyDown Hold
    6. */
    7. #region Propertys
    8. private string _Text;
    9. public new string Text {
    10. get => _Text;
    11. set => PropertyChange(ref _Text, value, () => {
    12. BeforeTextChanged?.Invoke(this, CursorPosition);
    13. this.Invalidate();
    14. AfterTextChanged?.Invoke(this, CursorPosition);
    15. });
    16. }
    17. private Padding _TextPadding;
    18. public Padding TextPadding { get => _TextPadding; set => PropertyChange(ref _TextPadding, value, Invalidate); }
    19. private string _CueText;
    20. public string CueText {
    21. get => _CueText;
    22. set => PropertyChange(ref _CueText, value, Invalidate);
    23. }
    24. private Color _CueColor;
    25. public Color CueColor {
    26. get => _CueColor;
    27. set => PropertyChange(ref _CueColor, value, Invalidate);
    28. }
    29. private ContentAlignment _ContentAlignment;
    30. public new ContentAlignment ContentAlignment {
    31. get => _ContentAlignment;
    32. set => PropertyChange(ref _ContentAlignment, value, Invalidate);
    33. }
    34. private Color _LineColor;
    35. public Color LineColor {
    36. get => _LineColor;
    37. set => PropertyChange(ref _LineColor, value, Invalidate);
    38. }
    39. private int _LineHeight;
    40. public int LineHeight {
    41. get => _LineHeight;
    42. set => PropertyChange(ref _LineHeight, value, Invalidate);
    43. }
    44. private int _LineMarginLeft;
    45. public int LineMarginLeft {
    46. get => _LineMarginLeft;
    47. set => PropertyChange(ref _LineMarginLeft, value, () => {
    48. LineMarginHorizontal = -1;
    49. _LineMarginLeft = value;
    50. });
    51. }
    52. private int _LineMarginRight;
    53. public int LineMarginRight {
    54. get => _LineMarginRight;
    55. set => PropertyChange(ref _LineMarginRight, value, () => {
    56. LineMarginHorizontal = -1;
    57. _LineMarginRight = value;
    58. });
    59. }
    60. private int _LineMarginHorizontal;
    61. public int LineMarginHorizontal {
    62. get => _LineMarginHorizontal;
    63. set => PropertyChange(ref _LineMarginHorizontal, value, () => {
    64. if (value != -1) {
    65. LineMarginLeft = value;
    66. LineMarginRight = value;
    67. }
    68. Invalidate();
    69. });
    70. }
    71. private int _LineMarginBotton;
    72. public int LineMarginBotton {
    73. get => _LineMarginBotton;
    74. set => PropertyChange(ref _LineMarginBotton, value, Invalidate);
    75. }
    76. private Color _ForeColor;
    77. public new Color ForeColor {
    78. get => _ForeColor;
    79. set => PropertyChange(ref _ForeColor, value, Invalidate);
    80. }
    81. private Color _BackColor;
    82. public new Color BackColor {
    83. get => _BackColor;
    84. set => PropertyChange(ref _BackColor, value, Invalidate);
    85. }
    86. private int _CursorSpeed;
    87. public int CursorSpeed {
    88. get => _CursorSpeed;
    89. set => PropertyChange(ref _CursorSpeed, value, Invalidate);
    90. }
    91. private int _CourserWidth;
    92. public int CursorWidth {
    93. get => _CourserWidth;
    94. set => PropertyChange(ref _CourserWidth, value, Invalidate);
    95. }
    96. private int _CursorPosition;
    97. public int CursorPosition {
    98. get => _CursorPosition;
    99. set => PropertyChange(ref _CursorPosition, value, Invalidate);
    100. }
    101. private Font _Font;
    102. public new Font Font {
    103. get => _Font;
    104. set => PropertyChange(ref _Font, value, Invalidate);
    105. }
    106. #endregion
    107. public event Action<Object> MarginChange;
    108. public event Action<Object, int> BeforeTextChanged;
    109. public event Action<Object, int> AfterTextChanged;
    110. public CueTextBox() {
    111. ControlStyles styles = ControlStyles.UserPaint
    112. | ControlStyles.OptimizedDoubleBuffer
    113. | ControlStyles.SupportsTransparentBackColor
    114. | ControlStyles.ResizeRedraw
    115. | ControlStyles.UseTextForAccessibility
    116. | ControlStyles.Selectable;
    117. SetStyle(styles, true);
    118. //Font = Parent.Font;
    119. }
    120. //Test
    121. bool select;
    122. bool usercursorSet;
    123. //
    124. protected override void OnClick(EventArgs e) {
    125. select = true;
    126. }
    127. protected override void OnKeyDown(KeyEventArgs e) {
    128. string letter = e.KeyCode.ToString();
    129. if (Regex.IsMatch(letter, "^(?:\\w|\\s|\\d){0,1}$")) {
    130. if (string.IsNullOrEmpty(Text)) {
    131. Text = letter;
    132. CursorPosition = Text.Length;
    133. } else {
    134. Text = string.Concat(Text, letter);
    135. CursorPosition = Text.Length;
    136. }
    137. Console.WriteLine(Text);
    138. Invalidate();
    139. Refresh();
    140. }
    141. }
    142. protected override void OnPaint(PaintEventArgs e) {
    143. Graphics graphics = e.Graphics;
    144. Rectangle rect = Bounds;
    145. #region UnderLine
    146. Pen linePen = new Pen(LineColor, LineHeight);
    147. int lineXStart = LineMarginLeft;
    148. int lineXEnd = rect.Width - LineMarginRight;
    149. int lineYEnd = rect.Height - (LineMarginBotton + LineHeight);
    150. Point lineStartLoc = new Point(lineXStart, lineYEnd);
    151. Point lineEndLoc = new Point(lineXEnd, lineYEnd);
    152. graphics.DrawLine(linePen, lineStartLoc, lineEndLoc);
    153. #endregion
    154. #region Text
    155. string printText = Text;
    156. Color textColor = ForeColor;
    157. if (string.IsNullOrEmpty(Text) && false) {
    158. printText = CueText;
    159. textColor = CueColor;
    160. }
    161. Size textSize = TextRenderer.MeasureText(printText, Font);
    162. textSize.Width += TextPadding.Right;
    163. textSize.Height += TextPadding.Bottom;
    164. Point textLoc = new Point(TextPadding.Left, TextPadding.Top);
    165. Rectangle textRect = new Rectangle(textLoc, textSize);
    166. TextRenderer.DrawText(graphics, printText, Font, textRect, textColor);
    167. #endregion
    168. #region Cursor
    169. if (true && !string.IsNullOrEmpty(Text)) {
    170. string onCT = Text.Substring(0, CursorPosition);
    171. Size tcSize = TextRenderer.MeasureText(onCT, Font);
    172. int cursorX = tcSize.Width + 1;
    173. int cursorY = textLoc.Y;
    174. Point cursorLoc = new Point(cursorX, cursorY);
    175. Size cursorSize = new Size(CursorWidth, tcSize.Height);
    176. Rectangle cursorRect = new Rectangle(cursorLoc, cursorSize);
    177. using (SolidBrush cursorBrush = new SolidBrush(Color.Black)) {
    178. graphics.FillRectangle(cursorBrush, cursorRect);
    179. }
    180. }
    181. #endregion
    182. }
    183. protected override Cursor DefaultCursor {
    184. get {
    185. return Cursors.IBeam;
    186. }
    187. }
    188. protected override bool IsInputKey(Keys keyData) {
    189. if ((keyData & Keys.Alt) != Keys.Alt) {
    190. switch (keyData & Keys.KeyCode) {
    191. case Keys.Tab:
    192. case Keys.Escape:
    193. return false;
    194. case Keys.Back:
    195. return true;
    196. case Keys.PageUp:
    197. case Keys.PageDown:
    198. case Keys.Home:
    199. case Keys.End:
    200. return true;
    201. }
    202. }
    203. return base.IsInputKey(keyData);
    204. }
    205. }
    206. }
    Genau. Jene transparente TextBox plus ein farbliches Panel (welches die Linie darstellt) in ein UserControl. Und dann hiermit einen eigenen Cursor definieren.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed Das mit dem Caret funktioniert bei mir (Studio 2013, W10) nicht. ;(
    @Facebamm Mach Dir ein UserControl mit einer TextBox und einer Linie, die kannst Du im Paint-Event zeichnen.
    BackColor von UserControl und TextBox gleich, TextBox: BorderStyle = None
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ist ein bisken tricky, da man bei jedem TextBox-Betreten ShowCaret anwenden muss.
    Ich hab das Caret-Ändern mal in einen Button getan:

    C#-Quellcode

    1. private void button1_Click(object sender, EventArgs e)
    2. {
    3. CreateCaret(textBox1.Handle, GetHBitmap(), 10, textBox1.Height );
    4. ShowCaret(textBox1.Handle);
    5. }
    6. private IntPtr GetHBitmap()
    7. {
    8. Bitmap bm= (Bitmap) Image.FromFile(DateiPfad, true);
    9. return bm.GetHbitmap();
    10. }

    Achtung! Das Bild muss farbinvertiert werden! Denn in der Textbox selber wird es wieder invertiert dargestellt.

    Ergebnis:
    (Original, was man später sehen will) => (per paint.net farbinvertiert; auf dieses Bild muss man in CreateCaret verweisen) ==>


    (Ergebnis, bei dem das Bild als Cursor verwendet wird.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed OK.
    Solange die TextBox NICHT den Fokus hat, wird dieser Cursor angezeigt.
    Klickt man in die TextBox, ist der Standardcursor wieder aktiv.
    Klick raus -> Cursor ist Cursor ist weiterhin der Standardcursor.
    Wenn man Deinen Code in das .Leave-Event der TextBox schreibt, ist der neue Cursor nur beim Nicht-Editieren aktiv.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Die Funktionen CreateCaret und ShowCaret müssen ins GotFocus-Ereignis.
    Ins Leave-Ereignis soll wohl die DestroyCaret-Funktion. Beispiel anbei.

    Ich arbeite nicht oft mit C#, daher hatte ich etwas Schwierigkeiten mit dem Einbinden der Bitmap-Datei RedCaret. Aber es geht ja ums Prinzip.
    Dateien
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Die MetroSuite könnte ebenfalls genau das :)
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    GDI+
    Das Ganze Control ist gezeichnet. Da wird nix mit Panels gearbeitet haha
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Diesbezüglich wird ein unsichtbares Textboxelement erzeugt.
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!