UWP等待Textbox.Textchanged事件触发

时间:2019-01-17 14:45:51

标签: c# uwp textbox textchanged

如何在UWP文本框中更改文本并等待TextChanged完成后再继续操作,或者根本不触发TextChanged事件。

场景。 如果TextBox文本更改,主UI会显示一个红色标记-但是,我偶尔需要重置它(TextBox.Text =“”或其他一些文本),当这种情况发生时,我希望红色标记变为绿色。

预期流程

TextBox.Text = ""
TextBox.Changed event fires - causing my flag to go red
Reset flag to green

实际流程

TextBox.Text = ""
Reset flag to green
TextBox.Changed event fires - causing my flag to go red

我认为正在发生的事情 设置TextBox.Text会导致将一个事件添加到调度队列,该事件在UI线程空闲之前不会触发,这意味着下一个命令(将Reset标志更改为绿色)发生在消费TextChanged事件之前。事件也有可能在触发事件之前正在等待TextBox完成渲染,但是我不确定。

解决方案? 任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:0)

答案很简单:使用布尔标志来区分何时触发“红色标志”和何时触发绿色标志。

答案 1 :(得分:0)

In "real life", I would be creating a custom control based on a textbox and defining all of the states in Blend and probably add a dirty state or something and drive it all via a boolean property. However, here some proof of concept code that seems to do what I gather you need. I think the only real difference to what you have been trying is that I am tracking the "old value" and comparing it when the text changes to determine its cleanliness. The magic reset also controls that old value.

control code:

namespace DirtyTextBox
{
    public class DirtyNotifyingTextBox : TextBox
    {
        public DirtyNotifyingTextBox()
        {
            this.DefaultStyleKey = typeof(TextBox);
            DataContextChanged += DirtyNotifyingTextBox_DataContextChanged;
        }

        private void DirtyNotifyingTextBox_DataContextChanged(Windows.UI.Xaml.FrameworkElement sender, Windows.UI.Xaml.DataContextChangedEventArgs args)
        {
            _originalValue = this.Text;
            TextChanged += DirtyNotifyingTextBox_TextChanged;
            SetToGreen();
        }

        private string _originalValue { get; set; }

        private void DirtyNotifyingTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (this.Text != _originalValue)
            {
                SetToRed();
            }
            else
            {
                SetToGreen();
            }
        }

        private void SetToGreen()
        {
            this.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 50, 205, 0));
        }

        private void SetToRed()
        {
            this.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 255, 0, 0));
        }

        public void Reset()
        {
            Reset(string.Empty);
        }

        public void Reset(string resetValue)
        {
            _originalValue = resetValue;
            this.Text = resetValue;
        }

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }
    }
}

sample usage:

<StackPanel Orientation="Horizontal">
    <local:DirtyNotifyingTextBox x:Name="dtextbox" Width="250" Height="50" />
    <Button Content="reset" Click="Reset" Margin="10 0" />
    <Button Content="reset with value" Click="ResetWithValue" Margin="10 0" />
    <Button Content="change text with code" Click="UpdateText" Margin="10 0" />
</StackPanel>

code behind:

private void Reset(object sender, RoutedEventArgs e)
{
    dtextbox.Reset();
}

private void ResetWithValue(object sender, RoutedEventArgs e)
{
    dtextbox.Reset("Magic Reset");
}

private void UpdateText(object sender, RoutedEventArgs e)
{
    dtextbox.Text = "updated text";
}