如何在TextCompositionEventArgs中更改Text

hap*_*rst 6 c# wpf datagrid textbox textinput

C#WPF - 我有一个自定义的可编辑数据网格,它使用我自己的继承自DataGridTextColumn的自定义列.在我的列类中,我重写了GenerateEditingElement,以便我可以自动设置MaxLength,CharacterCasing等内容.

问题是,当用户突出显示一个单元格,然后键入他们的第一个字符时,datagrid会自动进入editmode.所以我的GenerateEditingElement会触发,我可以设置文本框.不幸的是,这对于角色来说太晚了,而且TextCompositionEventArgs中已经有一个小写字母.后续类型字符是正确的情况.

列类PrepareCellForEdit是下一个触发的,它有TextCompositionEventArgs.但是,我似乎无法改变文字.我遇到了setter不可用的编译错误.(即使知识的智能帮助确实说得到并设置).

无论如何我可以通过编程方式将我的字符串放入文本框中吗?或者我如何在TextCompositionEventArgs中更改该文本?

ask*_*msk 0

主要思想是订阅TextBox的TextChanged事件。但技巧是您无法直接在此事件处理程序上更新 Text 属性。您必须使用一些小的延迟来执行此操作。这是运行正常的示例:

    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;
    }
Run Code Online (Sandbox Code Playgroud)