2012-02-28 58 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; 
    }