2012-02-28 60 views
7

C#WPF - 我有一個自定義的可編輯的數據網格,使用我自己的自定義列從DataGridTextColumn繼承。在我的專欄類中,我重寫了GenerateEditingElement,以便我可以自動設置諸如MaxLength,CharacterCasing等的東西。如何更改TextCompositionEventArgs中的文本

問題是,當用戶突出顯示一個單元格時,然後輸入它們的第一個字符,datagrid會自動輸入editmode。所以我的GenerateEditingElement會觸發,我可以設置文本框。不幸的是,這對於特徵化來說已經太晚了,並且TextCompositionEventArgs已經有一個小寫的char。後續的類型字符是正確的。

列類PrepareCellForEdit是接下來觸發的,它有TextCompositionEventArgs。但是,我似乎無法改變文字。我得到編譯器錯誤,該編譯器不可用。 (儘管該物業的intellisense幫助確實說得到並設置)。

有無論如何我可以通過編程方式將我的charactercasing放入文本框? 或 如何更改TextCompositionEventArgs中的文本?

回答

0

主要想法是訂閱TextBox的TextChanged事件。 但技巧是你不能直接在這個事件處理程序上更新文本propery。 你必須使用一些小的延遲來做到這一點。 這裏是工作正常的例子:

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