2012-02-28 29 views
7

C# WPF - Tôi có một datagrid có thể chỉnh sửa tùy chỉnh sử dụng các cột tùy chỉnh của riêng tôi kế thừa từ DataGridTextColumn. Trong lớp cột của tôi, tôi ghi đè GenerateEditingElement để tôi có thể tự động thiết lập những thứ như MaxLength, CharacterCasing,…Cách thay đổi Văn bản trong TextCompositionEventArgs

Vấn đề là khi người dùng đánh dấu một ô, sau đó nhập ký tự đầu tiên của họ, tự động nhập dữ liệu vào editmode. Vì vậy, GenerateEditingElement của tôi kích hoạt và tôi có thể thiết lập hộp văn bản. Thật không may, điều này là quá muộn cho charactercasing và TextCompositionEventArgs đã có một trường hợp char thấp hơn trong đó. Các ký tự loại tiếp theo là trường hợp chính xác.

Lớp cột PrepareCellForEdit là những gì xảy ra tiếp theo và điều này có TextCompositionEventArgs. Tuy nhiên, tôi không thể thay đổi văn bản. Tôi nhận được lỗi biên dịch mà setter là không có sẵn. (mặc dù sự trợ giúp intellisense cho tài sản nói rằng có được và thiết lập).

Có cách nào tôi có thể lập trình lấy đặc điểm của mình vào hộp văn bản không? HOẶC Làm cách nào để thay đổi văn bản đó trong TextCompositionEventArgs?

Trả lời

0

Ý tưởng chính là đăng ký sự kiện TextChanged của TextBox. Nhưng lừa là bạn không thể cập nhật văn bản thích hợp trực tiếp trên trình xử lý sự kiện này. Bạn phải sử dụng một số độ trễ nhỏ để thực hiện việc này. Đây là ví dụ về công trình OK:

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