c# - WPF 文本框 : set cursor position to last character received on property changed handler in View Model

标签 c# wpf xaml mvvm

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

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

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

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

Image to help describe issue

我对为什么会发生这种情况感到困惑,并对如何处理这个问题的其他选择持开放态度。我已经考虑尝试将该文本框的 CaretIndex 绑定(bind)到我的 View 模型中的属性,但它无法绑定(bind),因此该选项已失效。任何其他关于我做错了什么的想法或见解将不胜感激。

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

View 模型:

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}"/>

最佳答案

为您的 TextBox 处理 SourceUpdated 事件(不要忘记在您的绑定(bind)中 NotifyOnSourceUpdated=True )将 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;
        }
    }

关于c# - WPF 文本框 : set cursor position to last character received on property changed handler in View Model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46067029/

相关文章:

c# - 网址没有命中任何 Action

c# - 声明一个具有增量值的数组 - 有捷径吗?

c# - wpf中如何让GridView支持多选

c# - 带有隐藏输入的 HttpWebRequest 登录

c# - 如何在 Windows 10 MapControl 中将 Z-Index 添加到 XAML 控件

c# - 在 C# 中运行 F# 代码 -(就像在 C# 中使用 Roslyn 的 C#)

c# - 在本地运行一次计时器触发的 Azure 函数的最简单方法是什么?

c# - 禁用按钮的上下文菜单

c# - 如何在 WPF 中从 mainwindow.xaml 导航到 page.xaml

c# - 绑定(bind)到 WPF 中的设计数据