如何以编程方式引发文本框TextChangedEvent

本文关键字:文本 TextChangedEvent 方式引 编程 | 更新日期: 2023-09-27 18:10:05

我在WPF项目中使用。net 4.5。我想引发一个TextBox TextChangedEvent。以下是我所做的:

tb.RaiseEvent(new RoutedEventArgs(TextBox.TextChangedEvent));

我在按钮上做了同样的RaiseEvent。之前的ClickEvent,我怎么做这个?

会产生如下错误:

异常:抛出:"Object of type 'System.Windows.RoutedEventArgs' "不能转换为类型‘System.Windows.Controls.TextChangedEventArgs’。"(System. argumentexception)ArgumentException被抛出:" System.Windows类型的对象。"RoutedEventArgs'不能被转换键入'System.Windows.Controls.TextChangedEventArgs'。"

[编辑]

实际更改的文本框文本由附加行为处理,如下所示。我想以编程方式引发事件的地方是在另一个控件的附加行为。在后面的行为中,我确实有textbox对象。

public class textboxTextChangedBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.TextChanged += OnTextChanged;
    }
    protected override void OnDetaching()
    {
        AssociatedObject.TextChanged -= OnTextChanged;
        base.OnDetaching();
    }
    private void OnTextChanged(object sender, TextChangedEventArgs args)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {
            //Populate ObservableCollection
        }
    }
}

尝试触发事件的位置:

public class FindPopupBehavior : Behavior<Popup>
{
    protected override void OnAttached()
    {
        AssociatedObject.Opened += _OpenFindPopup;
    }
    protected override void OnDetaching()
    {
        AssociatedObject.Opened -= _OpenFindPopup;
    }
    void _OpenFindPopup(object sender, EventArgs e)
    {
        //Fake a TextBox text changed event
        if (TextBoxObject == null)
            return;
        TextBox tb = TextBoxObject as TextBox;
        if (tb.Text == "")
            return;
        tb.RaiseEvent(new RoutedEventArgs(TextBox.TextChangedEvent));
    }
    public static readonly DependencyProperty TextBoxProperty =
        DependencyProperty.Register("TextBoxObject", typeof(TextBox), typeof(FindPopupBehavior), new UIPropertyMetadata(null));
    public object TextBoxObject
    {
        get { return (object)GetValue(TextBoxProperty); }
        set { SetValue(TextBoxProperty, value); }
    }
}

[EDIT2]

文本框驻留在弹出窗口中,当这个弹出窗口关闭时,ObservableCollection被清除,文本框文本保留,尽管隐藏。如果弹出窗口重新打开,并且文本框中有文本,则需要重新填充ObservableCollection。它在textchanged行为中进行填充。这就是为什么我想搞个活动

如何以编程方式引发文本框TextChangedEvent

手动引发。net事件是不可取的,即使没有其他原因,只是不需要。想想看……你不会真的想要引发一个事件。你不是在寻求事件的功能性,那么为什么要提出它呢?

如果我正确理解了你的情况,那么可以肯定的是,你实际上想要做的是执行代码的特定部分。因此,造成问题的原因是该代码段目前被封装在事件处理程序中。但是,并不意味着必须触发该事件才能执行该代码。

相反,只需简单地将相关代码移动到一个方法中,您可以从事件处理程序从任何您想要的地方调用该方法,而不必引发任何事件:
private void OnTextChanged(object sender, TextChangedEventArgs args)
{
    var textBox = (sender as TextBox);
    if (textBox != null)
    {
        PopulateObservableCollection();
    }
}
private void PopulateObservableCollection()
{
    // Populate ObservableCollection
}

如果您特别需要访问TextBox,那么请进一步描述您的情况…总有一条路。


更新>>>

从逻辑上想一想……你想调用这个方法,你需要访问Popup中的TextBox,你需要每次打开Popup时都这样做。那么为什么不直接处理Popup.Opened事件呢?:

private void PopupOpened(object sender, EventArgs e)
{
    // Check TextBox and Populate ObservableCollection
}

您可以像

那样手动引发事件
    MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice,100, MouseButton.Left);
    args.RoutedEvent = UIElement.PreviewMouseLeftButtonUpEvent;
    tb.RaiseEvent(args);

你可以这样做…

   EventName.Raise(this, new EventArgs());

为什么不直接调用事件的方法呢?我已经为您创建了一个小的示例应用程序:

执行以下操作:

    我有一个按钮和一个文本框。文本框上有一个OnTextChanged事件,我想当我点击按钮时,执行那个文本框事件。

首先,你的WPF应用程序,在我的例子中,只包含一个网格,其中有一个文本框和一个按钮。

<Grid>
    <TextBox Name="txtTextBox"></TextBox>
    <Button Name="btnDemo" Content="Click me"></Button>
</Grid>

我知道布局明智,这是垃圾,但这只是为了演示。

在后面的代码中,需要做一些事情:

为按钮和文本框添加事件处理程序:

public MainWindow()
{
    InitializeComponent();
    btnDemo.Click += BtnDemoOnClick;
    txtTextBox.TextChanged += TxtTextBoxOnTextChanged;
}

下面是你的TxtTextBoxOnTextChanged事件的代码:

private void TxtTextBoxOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
{
    MessageBox.Show("The textbox event has been fired.");
}

如您所见,这只是显示一个消息框。

然后是按钮的事件:

private void BtnDemoOnClick(object sender, RoutedEventArgs routedEventArgs)
{
    TxtTextBoxOnTextChanged(this, new TextChangedEventArgs(routedEventArgs.RoutedEvent, UndoAction.None));
}

希望有帮助。

这可能以stackoverflow结束,因为如果为您的对象召回事件,它将再次被您的textboxTextChangedBehavior捕获

所以你可以简单地改变

而不是创建一个循环
private void OnTextChanged(object sender, TextChangedEventArgs args)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {}
    }

private void OnTextChanged(object sender, TextChangedEventArgs args)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {}
        // now your textboxTextChangedBehavior does't block your event 
        args.Handled = false;
    }

[编辑]

也许问题更在于你如何努力实现你的目标。

但是如果我正确理解你的弹出Opened和你试图提高TextChanged,对吗?

所以你可以在_OpenFindPopup中设置文本(添加一个#或者其他什么)这样就会抬高你的TextChanged现在你可以移除#填充你的ObservableCollection