2009-08-19 14 views
17

Dato un controllo TextBox WinForms con MultiLine = true e AcceptsTab == true, come è possibile impostare la larghezza del carattere di tabulazione visualizzata?Come impostare la larghezza del TAB in un controllo TextBox di Windows Form?

Voglio usare questo come una casella di input di script veloce e sporco per un plugin. E 'davvero non ha bisogno di essere di fantasia a tutti, ma sarebbe bello se le schede non sono stati visualizzati come larga 8 caratteri ...

Dalla risposta accettata:

// set tab stops to a width of 4 
private const int EM_SETTABSTOPS = 0x00CB; 

[DllImport("User32.dll", CharSet = CharSet.Auto)] 
public static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam); 

public static void SetTabWidth(TextBox textbox, int tabWidth) 
{ 
    Graphics graphics = textbox.CreateGraphics(); 
    var characterWidth = (int)graphics.MeasureString("M", textbox.Font).Width; 
    SendMessage(textbox.Handle, EM_SETTABSTOPS, 1, 
       new int[] { tabWidth * characterWidth }); 
} 

Questo può essere chiamato in il costruttore del tuo Form, ma attenzione: assicurati che InitializeComponents venga eseguito per primo.

+1

È necessario disporre anche di elementi grafici, magari inserirli nell'istruzione. –

risposta

7

So che si sta utilizzando un TextBox momento, ma se si riesce a cavarsela con l'utilizzo di un RichTextBox al contrario, è possibile utilizzare la proprietà SelectedTabs per impostare la larghezza della tabulazione desiderata:

richTextBox.SelectionTabs = new int[] { 15, 30, 45, 60, 75}; 

Si noti che questi offset sono pixel, non caratteri.

5

L'esempio offerto non è corretto.

Il messaggio EM_SETTABSTOPS prevede che le dimensioni delle schede siano specificate in dialog template units e non in pixel. Dopo alcuni scavi, sembra che un'unità di modello di dialogo sia uguale a 1/4th the average width of the window's character. Quindi dovrai specificare da 8 per 2 caratteri di lunghezza, 16 per quattro caratteri e così via.

modo che il codice può essere semplificata come:

public static void SetTabWidth(TextBox textbox, int tabWidth) 
{ 
    SendMessage(textbox.Handle, EM_SETTABSTOPS, 1, 
      new int[] { tabWidth * 4 }); 
} 
+0

Grazie, Loris, non ne ero a conoscenza. –

6

Con l'uso di metodi di estensione, è possibile aggiungere un nuovo metodo alla classe controllo TextBox. Questo è il mio attuazione (tra cui un metodo di estensione aggiuntiva che ti dà le coordinate per la posizione corrente del cursore di inserimento) da quello che ho raccolto dai contributori precedenti sopra:

using System; 
using System.Drawing; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace Extensions 
{ 
    public static class TextBoxExtension 
    { 
     private const int EM_SETTABSTOPS = 0x00CB; 

     [DllImport("User32.dll", CharSet = CharSet.Auto)] 
     private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam); 

     public static Point GetCaretPosition(this TextBox textBox) 
     { 
      Point point = new Point(0, 0); 

      if (textBox.Focused) 
      { 
       point.X = textBox.SelectionStart - textBox.GetFirstCharIndexOfCurrentLine() + 1; 
       point.Y = textBox.GetLineFromCharIndex(textBox.SelectionStart) + 1; 
      } 

      return point; 
     } 

     public static void SetTabStopWidth(this TextBox textbox, int width) 
     { 
      SendMessage(textbox.Handle, EM_SETTABSTOPS, 1, new int[] { width * 4 }); 
     } 
    } 
} 
+0

grazie! questo è davvero fantastico! –

+0

Prego! In realtà un ulteriore raffinamento che ho aggiunto al mio codice controlla per assicurarsi che il TextBox sia Multiline e AcceptsTab sia abilitato. –

+0

Grazie, Brien, è un modo molto carino per incapsulare questa funzionalità! – BillW

1

Per chi vuole diverse larghezze tab, ho ha adottato questo approccio:

using System.Runtime.InteropServices; 

[DllImport("User32.dll", CharSet = CharSet.Auto)] 
private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, uint[] lParam); 
private const int EM_SETTABSTOPS = 0x00CB; 

private void InitialiseTabStops() 
{ 
    // Declare relative tab stops in character widths 
    var tabs = new uint[] { 2, 2, 4, 8, 2, 32 }; 

    // Convert from character width to 1/4 character width 
    for (int position = 0; position < tabs.Length; position++) 
     tabs[position] *= 4; 

    // Convert from relative to absolute positions 
    for (int position = 1; position < tabs.Length; position++) 
     tabs[position] += tabs[position - 1]; 

    SendMessage(textBox.Handle, EM_SETTABSTOPS, tabs.Length, tabs); 
} 
Problemi correlati