2012-02-28 7 views
7

C# WPF: tengo una cuadrícula de datos editable personalizada que utiliza mis propias columnas personalizadas que heredan de DataGridTextColumn. En mi clase de columna anulo GenerateEditingElement para que pueda establecer automáticamente cosas como MaxLength, CharacterCasing, etc.Cómo cambiar el texto en TextCompositionEventArgs

El problema es que cuando el usuario resalta una celda, luego escribe su primer caracter, la cuadrícula de datos ingresa automáticamente en el modo de edición. Así que mi GenerateEditingElement dispara y puedo configurar el cuadro de texto. Desafortunadamente, esto es demasiado tarde para caracterizar y TextCompositionEventArgs ya tiene un carácter en minúscula. Los tipos de caracteres posteriores son el caso correcto.

La clase de columna PrepareCellForEdit es lo que se activa a continuación y tiene el TextCompositionEventArgs. Sin embargo, parece que no puedo cambiar el texto. Obtengo errores de compilación que el colocador NO está disponible. (aunque la ayuda intellisense para la propiedad dice get y set).

¿Hay alguna manera de que pueda programar mi charactercasing en el cuadro de texto? O ¿Cómo puedo cambiar ese texto en TextCompositionEventArgs?

Respuesta

0

La idea principal es suscribirse al evento TextChanged de TextBox. Pero el truco es que no se pudo actualizar Text propery directamente en este controlador de eventos. Debe usar un pequeño retraso para hacer esto. Aquí está el ejemplo que funciona bien:

public struct MyData 
    { 
     public string Name { set; get; } 
    } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     ObservableCollection<MyData> oc = new ObservableCollection<MyData> { new MyData(), new MyData() }; 
     grid.ItemsSource = oc; 
    } 

    private void Grid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
    { 
     var col = new DataGridTextColumn(); 
     Style myStyle = new Style(typeof(TextBox)); 
     // subsribe to TextChanged event 
     myStyle.Setters.Add(new EventSetter(TextBoxBase.TextChangedEvent, new TextChangedEventHandler(OnTextChanged))); 
     col.EditingElementStyle = myStyle; 
     var binding = new Binding("Name") {Mode = BindingMode.TwoWay}; 
     col.Binding = binding; 
     e.Column = col; 
    } 

    private static void OnTextChanged(object sender, TextChangedEventArgs e) 
    { 
     TextBox textBox = sender as TextBox; 
     BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += Worker_DoWork; 
     worker.RunWorkerAsync(textBox); 
     worker.RunWorkerCompleted += Worker_RunWorkerCompleted;   
    } 

    static void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     TextBox textBox = e.Result as TextBox; 
     if (textBox != null) 
     { 
      textBox.Text = textBox.Text.ToUpper(); 
      textBox.CaretIndex = textBox.Text.Length; 
     } 
    } 

    static void Worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Thread.Sleep(1);// This is the trick :) 
     e.Result = e.Argument; 
    } 
Cuestiones relacionadas