加载控件时触发的文本更改事件,需要阻止加载



在我创建了一个控件,该控件具有一个文本框和附加的文本更改事件处理程序 - 这是在 xaml 中。

问题:加载控件时,会触发文本更改事件,我不希望仅在加载控件时才发生,当我通过键入某些内容实际使其更改控件时。

你们专业人士建议我怎么做?:)

您所要做的就是在处理文本框之前在事件处理程序中检查文本框的 IsLoaded 属性。

事件处理程序附加到构造函数中的 InitializeComponent 方法之后,而不是在 Xaml 中。

public MainWindow()
{
    InitializeComponent();
    textBox1.TextChanged+=new TextChangedEventHandler(textBox1_TextChanged);
}

注意到您正在谈论用户控件,我唯一能想到的就是创建一个可用于禁止 TextChanged 事件的属性,直到父窗体完成加载。看看这样的东西是否有效。

MainForm Xaml:

<my:UserControl1 setInhibit="True"   HorizontalAlignment="Left" Margin="111,103,0,0" x:Name="userControl11" VerticalAlignment="Top" Height="55" Width="149" setText="Hello" />

主表单 CS

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    userControl11.setInhibit = false;
}

用户控件:

public UserControl1()
{
    InitializeComponent();
    textBox1.TextChanged += new TextChangedEventHandler(textBox1_TextChanged);
}
public string setText
{
    get { return textBox1.Text; }
    set { textBox1.Text = value; }
}
public bool setInhibit { get; set; }
void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
    if (setInhibit) return;
    // Do your work here
}

UserControl1.xaml:

<Grid>
    <TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}" TextChanged="TextBox_TextChanged"/>
</Grid>

其中 TextChanged 是 TextBox 的原始事件

UserControl1.xaml.cs:

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        _isFirstTime = true;
        DataContext = this;
        InitializeComponent();
    }
    public event TextChangedEventHandler TextBoxTextChanged;
    bool _isFirstTime;
    //MyText Dependency Property
    public string MyText
    {
        get { return (string)GetValue(MyTextProperty); }
        set { SetValue(MyTextProperty, value); }
    }
    public static readonly DependencyProperty MyTextProperty =
        DependencyProperty.Register("MyText", typeof(string), typeof(UserControl1), new UIPropertyMetadata(""));
    private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (TextBoxTextChanged != null)
            if (!_isFirstTime)
            {
                TextBoxTextChanged(sender, e);
            }
        _isFirstTime = false;
    }
}

其中TextBox_TextChanged是原始文本更改的自定义事件处理程序而 TextBoxTextChanged 更像是原始 TextChanged 的包装器

Window.xaml:

<Grid>
    <c:UserControl1 TextBoxTextChanged="TextBoxValueChanged"/>
</Grid>

如您所见,您可以将事件处理程序添加到事件包装器(TextBoxTextChanged)

Window.xaml.cs:

private void TextBoxValueChanged(object sender, TextChangedEventArgs e)
{
    MessageBox.Show("asd");
}

最后,第一次更改文本时不会触发文本框值更改

private void TextBoxValueChanged(object sender, TextChangedEventArgs e)
    {
        if (Textbox1.IsFocused)
        {
            App.Current.Properties["TextChanged"] = "1"; // Set Flag
        }            
    }
private void TextBoxLostFocus(object sender, RoutedEventArgs e)
    {            
       if (App.Current.Properties["TextChanged"] == "1")
        {
            // Do Your Wor Here
            App.Current.Properties["TextChanged"] = "0"; // Clear Flag
        }
    }

在 XAML 上:

<TextBox xName="TextBox1" LostFocus="TextBoxLostFocus" TextChanged="TextBoxValueChanged"/>

(这是一个非常基本,肮脏的代码隐藏黑客...检查 IsLoaded 属性,如布伦特所述,我发现是有效的)

在这里,由于在创建文本框控件时它没有焦点,TextChanged 事件将触发,但标志"1"未设置......稍后当用户在编辑后离开字段时,由于它具有焦点,因此设置了标志... 将触发 LostFocus,但如果文本框已更改,则仅触发运行代码。

我找到了一种方法来防止跨多个输入的这种行为,而无需为每个输入创建一个唯一的布尔值......

private void TextChanged_UpdateItem(object sender, TextChangedEventArg e)
{
    TextBox txtBox = sender as TextBox;
    if (!txtBox.IsFocused)
        return;
    //The rest of your code here
    
}

所以基本上,如果文本字段没有焦点(如初始化),它只会返回。这也可以防止它在数据在其他位置更改时触发。:)

或者,正如布伦特所提到的,你可以只寻找"IsLoaded":

private void TextChanged_UpdateItem(object sender, TextChangedEventArg e)
{
    TextBox txtBox = sender as TextBox;
    if (!txtBox.IsLoaded)
        return;
    //The rest of your code here
    
}

最新更新