2012-02-28 31 views
7

C#WPF - DataGridTextColumnを継承する独自のカスタム列を使用するカスタム編集可能なDataGridがあります。私の列クラスでは、MaxLength、CharacterCasingなどのようなものを自動的に設定できるように、GenerateEditingElementをオーバーライドします。TextCompositionEventArgs内のテキストを変更する方法

問題は、ユーザーがセルをハイライト表示して最初の文字を入力すると、データグリッドが自動的にeditmodeになります。私のGenerateEditingElementが起動し、テキストボックスをセットアップすることができます。残念なことに、これは文字化には遅すぎ、TextCompositionEventArgsには既に小文字の文字が含まれています。後続の文字が正しい場合です。

PrepareCellForEditという列クラスは次に発生するもので、これにはTextCompositionEventArgsがあります。しかし、私はテキストを変更することはできません。私は、setterが利用できないというコンパイルエラーを受け取ります。 (たとえインテリセンスがプロパティの助けを得て設定すると言っても)。

私はプログラムで文字の中に文字を入れることができますか? OR TextCompositionEventArgsでそのテキストを変更するにはどうすればよいですか?

答えて

0

主なアイデアはTextBoxのTextChangedイベントを購読していることです。 しかし、このイベントハンドラでTextyプロパティを直接更新することはできませんでした。 これを行うには、少し遅延を使用する必要があります。 次の例は正常です:

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; 
    }