Bind static method from another class as handler for WPF control event - wpf

I have a window, say MainWindow with some NumericUpDowns. I have another window MyCalculatorWindow like this:
public class MyCalculatorWindow : Window {
public static void LongUpDown_TouchUp(object sender, TouchEventArgs e)
{
// Show calculator and set numeric value when OK button is pressed.
}
// The rest of the MyCalculator functionality...
}
Is there a way to bind that static method to the TouchUp event handler property of LongUpDowns in xaml (ideally to all of them at once)? Something like this:
<xctk:LongUpDown TouchUp="{Binding Something??? MyCalculator.LongUpDown_TouchUp}" />

Is there a way to bind that static method to the TouchUp event handler property of LongUpDowns in xaml (ideally to all of them at once)? Something like this:
No, there isn't. The XAML compiler can only find event handlers in the same class as the element itself.
You could define a TouchUp event handler in the code-behind file for the view where the <xctk:LongUpDown /> element is and call the static method from there. It's a one-liner:
private void Window65_TouchUp(object sender, TouchEventArgs e) => MyCalculatorWindow.LongUpDown_TouchUp(sender, e);

Related

How to handle a custom RoutedEvent fired from a UserControl from inside the ViewModel?

Currently I have a usercontrol that fires a registered RoutedEvent like this:
protected virtual void OnScrollEvent(object oldValue, object newValue)
{
AssociatedObject.RaiseEvent(new DateTimeEventArgs(OnVisualChartRangeChangedEvent, minDate, maxDate));
}
The mainwindow container currently handles this event by calling a method from the view like this.
<Grid>
<historicChart:HistoricChartControl behaviours:ChartBehavior.OnVisualChartRangeChanged="RoutedEventHandler"/>
</Grid>
and the code behind...
private void RoutedEventHandler(object sender, DateTimeEventArgs dateTimeEventArgs)
{
//do stuff here...
}
But what I would like is for this to conform to the MVVM model, so that my handler should be implemented the viewmodel and not in the view.
How can I do this? Could someone post me a brief example of how I could go about this?
Thanks in advnce
You can use the CallMethodAction to invoke your ViewModel handler.
See this on how to create an EventTrigger for your custom RoutedEvent :
Custom RoutedEvent as EventTrigger

How does the WPF event system know about the event route?

I am trying to understand how RoutedEvents work.
Well - I walked through some tutorials and understood why RoutedEvents are useful and how they work.
But there is one thing, that I don't get:
Let's say I wrote a class (e.g. "MyClass") , which has a RoutedEvent property, sth. like this:
public class MyClass
{
public static readonly RoutedEvent myEvent;
...
}
Well - just giving a property is not enough - so I have to register the RoutedEvent with the help of EventManager:
...
myEvent = EventManager.RegisterRoutedEvent("MyEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyClass));
...
Okay - now the WPF event system knows about THIS event.
If I do it that way, each class I write will have it's own RoutedEvent. But that makes no sense to me.
What I want, is that other classes listen to the same event - without being a type of MyClass.
For example:
I have a stackpanel and within the stackpanel is a button. Clicking the stackpanel will raise the onClick event. Clicking the button will raise the onClick event of the button - and then the onClick event on the stackpanel.
But how?
Sorry - it's hard for me to describe the problem - I am just too confused :)
Thx a lot.
CodeCannibal
What I want, is that other classes listen to the same event - without being a type of MyClass.
You expect the right from this and this is what it delivers. I mean by registering a RoutedEvent you are not strongly binding it to the type; instead you are bridging it using the string "MyEvent" EventManager.RegisterRoutedEvent("MyEvent", ...
RoutedEvent traverse through the logical tree and stops traversing when handled (exceptions are there).
So, StackPanel need not to be derived from MyClass. You just need to register the RoutedEvent at StackPanel by specifying the action/handler. Whenever the RoutedEvent traverse through StackPanel it will call the corresponding action.
For example:
UserControl1.cs
//Routed Event
public static readonly RoutedEvent ThisIsEvent = EventManager.RegisterRoutedEvent("ThisIs", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(UserControl1));
// .NET wrapper
public event RoutedEventHandler ThisIs
{
add { AddHandler(ThisIsEvent, value); }
remove { RemoveHandler(ThisIsEvent, value); }
}
//local handler where RaiseEvent is called
private void button1_Click(object sender, RoutedEventArgs e)
{
RaiseEvent(new RoutedEventArgs(ThisIsEvent));
}
And below is how you subscribe to that event in you XAML. You can also do this in your code file...
<StackPanel Orientation="Vertical" **local:UserControl1.ThisIs="StackPanel_ThisIs"** >
<local:UserControl1></local:UserControl1>
</StackPanel>
I hope this clear your doubts.

How to bind an item command in user conrol to viewmodel command?

I have an UserControl. In my UserControl i have a button that I want bind its command to my ViewModel command. Can I do this?
Yes, you could add a routed event to your user control which gets invoked when the button is pressed.
You can then use various techniques to invoke the view model verb when the user control event fires.
E.g. you could use an attached property, or I would recommend using an MVVM framework such as Caliburn.Micro which has Actions that makes it even more straightforward.
I found it...I can define a DependensyProperty typof RelayCommand in my usercontrol and bind my DependensyProperty to my ViewModel Command
I'm not really sure what you mean but I take a shot.
In your code behind, define a RoutedCommand:
public partial class MyUserControl : UserControl
{
public static RoutedCommand Click =
new RoutedCommand("Click", typeof(UserControl));
}
Then it the xaml, set up a command binding:
<UserControl.CommandBindings>
<CommandBinding
Command="{x:Static MyNameSpace:MyUserControl.Click}"
CanExecute="ClickCanExecute"
Executed="ClickExecuted"/>
</UserControl.CommandBindings>
Then add the handlers in the code behind:
private void ClickCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void ClickExecuted(object sender, ExecutedRoutedEventArgs e)
{
// TODO execution logic goes here
}
Was I close? :)

How to handle child event in parent control

In my main window, I have a child control(user control) which contains a text box . How can I handle the textchange event of the text box of child control in main(parent) window.
Please provide me some example with code as I am new to routing of events.
You should just be able to hook the event from the parent control. But since your parent control doesn't have a TextChanged event of its own, you'll need to use attached-property syntax:
<Window ...
TextBox.TextChanged="ChildTextBoxChanged">
and in your codebehind:
private void ChildTextBoxChanged(object sender, TextChangedEventArgs args)
{
...
}
You don't have to put the TextBox.TextChanged= on the Window specifically -- just any control that's a parent of the TextBox, i.e., any control that's a parent of your UserControl. The event will bubble up to each parent in turn, all the way up to the top-level Window, and can get handled anywhere along the way.
(Note that if anyone hooks the event and sets e.Handled = true, the event won't bubble past that point. Useful to know if you have handlers at multiple levels.)
this also helped me. I will have a event in the container of the child control and define the event in the code behind file. The event will handle all the text changed events for all the children.
<StackPanel TextBoxBase.TextChanged="test_TextChanged" Name="test">
<userControl/>
</StackPanel>
Create a event in your childcontrol -
public event TextChangedEventHandler TextChanged;
now add a handler for TextChanged event of TextBox in childcontrol -
private void TextBox_TextChanged(object sender, TextChangedEventArgs args)
{
if (TextChanged != null)
{
TextChanged.Invoke(this, args);
}
}
also update XAML for this handler -
<TextBox ... TextChanged="TextBox_TextChanged" ... />
Now, you have created a event in your childcontrol that fires when the Textbox's textchanged fires.
Now you only to add a handler for this event in mainwindow -
private void ChildControl_TextChanged(object sender, TextChangedEventArgs args)
{
//TODO: Add your further code here.
}

Expose a Click event of a button inside a UserControl in Silverlight

I have a button inside my UserControl. I have three instances of this UserControl on the same page.
How can I expose the click event of the button inside such that I can assign different events for each instance of my UserControl.
I think this is similar to concept behind exposing DependencyProperty but I don't understand how to do it for events.
Thanks.
I normally add an event of the same name (and same parameters) to the user control and subscribe to the child control's original event, so I can pass the event on:
public partial class ClickEventControl : UserControl
{
public event EventHandler<RoutedEventArgs> Click;
public ClickEventControl()
{
InitializeComponent();
}
private void aButton_Click(object sender, RoutedEventArgs e)
{
if (Click != null)
{
Click(sender, e);
}
}
}
I would also be interested if there is a more general way of doing it.

Resources