简体   繁体   English

UWP等待Textbox.Textchanged事件触发

[英]UWP wait for Textbox.Textchanged event to fire

How to change the text in a UWP Textbox and wait for it's TextChanged to complete before moving on, or not fire the TextChanged event at all. 如何在UWP文本框中更改文本并等待其TextChanged完成后再继续操作,或者根本不触发TextChanged事件。

The scenario. 该方案。 Main UI shows a red flag if the TextBox text changes - however, I need to reset it occasionally (TextBox.Text = "", or some other text), when that happens, I want my red flag to go green. 如果TextBox文本更改,主UI会显示一个红色标记-但是,我偶尔需要将其重置(TextBox.Text =“”或其他一些文本),当这种情况发生时,我希望红色标记变为绿色。

Expected process flow 预期流程

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

Actual process flow 实际流程

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

What I think is happening Setting the TextBox.Text causes an event to be added to dispatch queue, which doesn't fire until the UI thread is idle, this means the next command (Reset flag to green) happens before the TextChanged event is consumed. 我认为正在发生的事情设置TextBox.Text会导致将一个事件添加到调度队列中,直到UI线程空闲时才会触发该事件,这意味着在消耗TextChanged事件之前发生下一个命令(将标志重置为绿色) 。 It's also possible that the event is waiting for the TextBox to finish rendering before firing the event, but I can't be certain. 事件也有可能在触发事件之前正在等待TextBox完成渲染,但是我不确定。

Solution? 解? Any help appreciated. 任何帮助表示赞赏。

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

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. 在“现实生活”中,我将创建一个基于文本框的自定义控件,并在Blend中定义所有状态,并可能添加一个脏状态或某些东西,并通过布尔属性将其驱动。 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";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM