WPF文本框:将光标位置设置为在View Model中的属性更改处理程序上接收的最后一个字符

时间:2017-09-06 04:54:37

标签: c# wpf xaml mvvm

设置:通过Prism利用MVVM的WPF应用程序

在我的应用程序中,我有一个文本框,我在其中提示我的用户输入日期。 WPF文本框绑定到我的ViewModel继承BindableBase(使用Prism)。当我的日期文本框被更改时,我正在调用自定义方法将日期掩码应用于我的视图上的输入(MM / DD / YYYY)。在我的帮助方法中,我也注入“/”字符来强制执行我的格式。

问题:如果用户连续3次为前3个位置重复相同的数字,则光标将跳回到之前的输入之一(例如111)。如果在输入中的任何其他位置发生重复3,则不会发生这种情况。如果数字不重复(121)

,也不会发生这种情况

例如: 用户进入11月11日(1111) 当用户键入第三个1时,光标将在文本框中的第一个和第二个字符之间跳回

Image to help describe issue

我很难理解为什么会发生这种情况,并对如何处理此问题的其他选项持开放态度。我试着将该文本框的CaretIndex绑定到我的视图模型中的属性,但是它无法绑定以便选项不存在。任何其他想法或见解我做错了导致这一点将非常感激。

我的FormatDate方法有什么明显的问题会导致这个问题?甚至可以从ViewModel设置光标(插入符号索引)?

视图模型:

public class CheckInViewModel : BindableBase
{
    private string _dob;
    public string DOB
    {
        get { return _dob; }
        set { SetProperty(ref _dob, FormatDate(value)); }
    }

    private string FormatDate(string val)
    {
        string clean = new string(new string(val.Where(a => char.IsDigit(a)).ToArray()).Take(8).ToArray());
        char[] chars = { 'M', 'M','/', 'D', 'D','/', 'Y', 'Y', 'Y', 'Y' };
        int i = 0;
        foreach (char c in clean)
        {
            if (i == 2 || i == 5)
            {
                chars[i] = '/';
                i++;
            }
            chars[i] = c;
            i++;
        }
        return new string(chars);
    }
}

查看(相关文本框):

<TextBox Margin="20,3,5,13" Text="{Binding DOB, UpdateSourceTrigger=PropertyChanged}" MinWidth="120" materialDesign:HintAssist.Hint="Birthdate"  Style="{StaticResource MaterialDesignFloatingHintTextBox}"/>

1 个答案:

答案 0 :(得分:1)

处理TextBox的SourceUpdated事件(不要忘记绑定中的NotifyOnSourceUpdated = True)对其中最后一个字符的set carret索引。

<TextBox Margin="20,3,5,13" Text="{Binding DOB, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" MinWidth="120" materialDesign:HintAssist.Hint="Birthdate"  Style="{StaticResource MaterialDesignFloatingHintTextBox}" SourceUpdated="TextBox_SourceUpdated"/>

        private void TextBox_SourceUpdated(object sender, DataTransferEventArgs e)
    {
        var txtBx = sender as TextBox;
        if (txtBx == null || txtBx.Text==null) return;          
        if (txtBx.CaretIndex == 2 || txtBx.CaretIndex == 5)
        {
            txtBx.CaretIndex = txtBx.CaretIndex + 1;
        }
    }