Reputation: 2616
I'm using .net 4.5, in a WPF project. I would like to raise a TextBox TextChangedEvent. This is what I have done so:
tb.RaiseEvent(new RoutedEventArgs(TextBox.TextChangedEvent));
I've done the same sort of RaiseEvent on a Button.ClickEvent before, how can I do this one?
this produces an error as follows:
Exception:Thrown: "Object of type 'System.Windows.RoutedEventArgs' cannot be converted to type 'System.Windows.Controls.TextChangedEventArgs'." (System.ArgumentException) A System.ArgumentException was thrown: "Object of type 'System.Windows.RoutedEventArgs' cannot be converted to type 'System.Windows.Controls.TextChangedEventArgs'."
[EDIT]
The actual textbox text changed is handled by an attached behavior as follows. The place where I want to programmatically raise the event is in another control's attached behavior. In the later behavior I do have the textbox object.
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
}
}
}
Place where I try to raise the event:
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]
The textbox resides in a popup upon this popup closing an ObservableCollection is cleared, the textbox text remains, although hidden. If the popup is reopened and the textbox has text it needs to repopulate the ObservableCollection. It does this population in the textchanged behavior. This is why I was thinking to fake an event.
Upvotes: 3
Views: 6764
Reputation: 69959
Manually raising .NET events is unadvisable, even if for no other reason than it is unrequired. Think about it... you don't really want to raise an event. You're not seeking the functionality of the event, so why raise it?
If I understand your situation correctly, then surely, what you actually want to do is to execute a particular section of your code. As such, your problem is caused because that section of code is currently encapsulated within an event handler. However, that doesn't mean that you have to raise that event to execute that code.
Instead, just simply move the relevant code into a method, which you can call from the event handler and from wherever else you want and all without unnecessarily raising any events:
private void OnTextChanged(object sender, TextChangedEventArgs args)
{
var textBox = (sender as TextBox);
if (textBox != null)
{
PopulateObservableCollection();
}
}
private void PopulateObservableCollection()
{
// Populate ObservableCollection
}
If you particularly need to access the TextBox
, then please describe your situation further... there is always a way.
UPDATE >>>
Think about this logically... you want to call this method and you need access to the TextBox
in the Popup
and you need to do it each time the Popup
is opened. So why not just handle the Popup.Opened
Event?:
private void PopupOpened(object sender, EventArgs e)
{
// Check TextBox and Populate ObservableCollection
}
Upvotes: 2
Reputation: 5420
this could end in an stackoverflow because if recall the Event for your object it will again be catched by your textboxTextChangedBehavior
so instead of creating a loop you can simple change your
private void OnTextChanged(object sender, TextChangedEventArgs args)
{
var textBox = (sender as TextBox);
if (textBox != null)
{}
}
to
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;
}
mhh maybe the problem is more how you try to achieve your goal.
but if i understand you correctly your popup Opened
and you try to raise the TextChanged
, right?
so you could set the Text in your _OpenFindPopup
(add an # or what ever) which will raise your TextChanged
and now you can remove the # and populate your ObservableCollection
Upvotes: 0
Reputation: 5820
Why don't you call the method of the event directly? I have created a small sample application for you:
It does the following:
First, your WPF application, that in my case, contains just a grid with in it a textbox and a button.
<Grid>
<TextBox Name="txtTextBox"></TextBox>
<Button Name="btnDemo" Content="Click me"></Button>
</Grid>
I know that layout wise, this is rubbish, but it's just for demonstrating.
In your code behind, you need to do a few things:
Add an event handler for the button and for the textbox:
public MainWindow()
{
InitializeComponent();
btnDemo.Click += BtnDemoOnClick;
txtTextBox.TextChanged += TxtTextBoxOnTextChanged;
}
Here's the code for your TxtTextBoxOnTextChanged event:
private void TxtTextBoxOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
{
MessageBox.Show("The textbox event has been fired.");
}
As you see, this just shows an message box.
And then the event of your button:
private void BtnDemoOnClick(object sender, RoutedEventArgs routedEventArgs)
{
TxtTextBoxOnTextChanged(this, new TextChangedEventArgs(routedEventArgs.RoutedEvent, UndoAction.None));
}
I hope it helped.
Upvotes: 0
Reputation: 7601
You can raise event manully like
MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice,100, MouseButton.Left);
args.RoutedEvent = UIElement.PreviewMouseLeftButtonUpEvent;
tb.RaiseEvent(args);
Upvotes: 1
Reputation: 1
One way is that you can do like this..
EventName.Raise(this, new EventArgs());
Upvotes: 0