so i want to outsource some things from MainWindow.xaml to App.xaml like this for example :
<Application x:Class="SVGTesting.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type ContentControl}" x:Key="Test1">
<StackPanel Orientation="Horizontal">
<Button Content="Button1" Click="Button_Click" x:Name="Button1"/>
<Button Content="Button2" Click="Button_Click" x:Name="Button2"/>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
In MainWindow.xaml then i have something like this
<ContentControl ContentTemplate="{StaticResource Test1}"/>
But now VS says that i cannot use the function "Button_Click" because its not in the codebehind from App.xaml. So how can i call this function from MainWindow in App.xaml?
Is there any way? I don't want answers like MVVM or Command. If it's not possible to solve then WPF is unfortunately useless for me.
Thanks and Greetings.
This is not the easiest thing to do as WPF expect things to be done in its own way. But there's few options, from easiest to hardest.
1. Don't do anything
Easiest way is to keep your data templates inside the MainWindow.xaml.
2. Use Commands instead of event handlers
You currently have event handlers defined like this:
<Button Content="Button1" Click="Button_Click"
"More-WPF way" of doing this would be to replace Click's event handler with a command with this quite cumbersome syntax:
<Button Content="Test" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.OnClickCommand}"></Button>
And then define the command in your MainWindow:
public ICommand OnButtonClick
{
get
{
return new Command(() =>
{
this.Text.Text = "Updated";
});
}
}
3. Define the event handlers in App.xaml.cs and use that to route the event handlers
I don't recommend this as it get tiresome to keep things synced but it's possible. Create and event handler in App.xaml.cs:
public partial class App : Application
{
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
Then use the sender to access the MainWindow instance and call it's method:
private void Button_Click(object sender, RoutedEventArgs e)
{
var mainWindow = (MainWindow)Window.GetWindow((DependencyObject)sender);
mainWindow.DoWork();
}
In my second example Command is defined like the following:
public class Command : ICommand
{
public delegate void ICommandOnExecute();
private ICommandOnExecute _execute;
public event EventHandler CanExecuteChanged;
public Command(ICommandOnExecute onExecuteMethod)
{
_execute = onExecuteMethod;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_execute?.Invoke();
}
}
You can't do it. See MSDN documentation for Code-Behind:
The event handlers you write must be instance methods defined by the
partial class within the namespace identified by x:Class. You cannot
qualify the name of an event handler to instruct a XAML processor to
look for that handler in a different class scope. You also cannot use
a static method as an event handler.
In WPF you can use a behaviors instead.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<Button Content="btnWithBehavior">
<i:Interaction.Behaviors>
<local:HandleButtonClick/>
</i:Interaction.Behaviors>
</Button>
public class HandleButtonClick : Behavior<Button>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Click += AssociatedObject_Click; ;
}
private void AssociatedObject_Click(object sender, RoutedEventArgs e)
{
//Move your MainWindow.Button_Click here;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Click -= AssociatedObject_Click;
}
}
Related
There is a textbox in my mainwindow.xaml, when I enter the textbox, I expect the label in my usercontrol, known as View1.xaml will be update accordingly. However I realise the event is not raise at all in the user control when I type the textbox, can you tell me which part is wrong?
The event is able to raise in TextBox_TextChanged_1
my MainWindow.XAML
<Window xmlns:my="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:testapplication" x:Class="testapplication.MainWindow"
Title="MainWindow" Height="964" Width="790">
<Grid >
<Button x:Name="OpenView1" Content="Open Window 1" HorizontalAlignment="Left" Margin="33,70,0,0" VerticalAlignment="Top" Width="111" RenderTransformOrigin="0.279,1.409" Click="OpenView1_Click"/>
<Button x:Name="OpenView2" Content="Open Window 2" HorizontalAlignment="Left" Margin="33,169,0,0" VerticalAlignment="Top" Width="111" Click="OpenView2_Click"/>
<Button x:Name="OpenView3" Content="Open Window 3" HorizontalAlignment="Left" Margin="33,259,0,0" VerticalAlignment="Top" Width="111" Click="OpenView3_Click"/>
<local:View1 x:Name="ViewOne" HorizontalAlignment="Left" Margin="33,332,0,0" VerticalAlignment="Top" Height="226" Width="204" Visibility="Hidden"/>
<local:View2 x:Name="ViewTwo" HorizontalAlignment="Left" Margin="284,332,0,0" VerticalAlignment="Top" Height="226" Width="208" Visibility="Hidden"/>
<local:View3 x:Name="ViewThree" HorizontalAlignment="Left" Margin="534,332,0,0" VerticalAlignment="Top" Height="226" Width="196" Visibility="Hidden"/>
<TextBox HorizontalAlignment="Left" Height="42" Margin="326,70,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="182" FontSize="22" TextChanged="TextBox_TextChanged_1"/>
</Grid>
</Window>
my MainWindow.cs
namespace testapplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
//InitializeComponent();
}
//event handler
public event EventHandler<EventArgs> changedText;
private void OpenView1_Click(object sender, RoutedEventArgs e)
{
ViewOne.Visibility = Visibility.Visible;
}
private void OpenView2_Click(object sender, RoutedEventArgs e)
{
ViewTwo.Visibility = Visibility.Visible;
}
private void OpenView3_Click(object sender, RoutedEventArgs e)
{
ViewThree.Visibility = Visibility.Visible;
}
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
if (changedText != null)
{
changedText(this, e);
}
}
}
}
This is my UserControl, known as View1.xaml, it is included in my MainWindow.Xaml
namespace testapplication
{
/// <summary>
/// Interaction logic for View1.xaml
/// </summary>
public partial class View1 : UserControl
{
private MainWindow newWindow = new MainWindow();
public View1()
{
InitializeComponent();
newWindow.changedText += newWindow_ChangeText;
}
void newWindow_ChangeText(object sender, EventArgs e)
{
ViewOnelabel.Content = "Happy";
}
}
}
The problem is my ViewOnelabel.Content = "Happy" did not execute at all, it remain unchanged
There are a few things I would like to point out.
The equivalent of a winforms label in wpf is a TextBlock. A wpf label is actually a type of contentcontrol. Hence the content property.
In wpf there are routed events. These "bubble" up ( and tunnel down ) the visual tree. That means you can handle an event in the window from a control in a usercontrol inside it.
But mainly.
I encourage you to look into the MVVM pattern.
I've put together some code which illustrates these points.
I'd recommend just using binding and mvvm though.
My MainWindow markup:
Title="MainWindow" Height="350" Width="525"
TextBoxBase.TextChanged="Window_TextChanged"
>
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<StackPanel>
<Label Name="OutputLabel"/>
<TextBlock Text="{Binding OutputString}"/>
<local:UserControl1/>
</StackPanel>
</Grid>
Notice that it handles a textchanged event and because that's routing it will get the event from UserControl1 inside it.
Code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_TextChanged(object sender, TextChangedEventArgs e)
{
OutputLabel.Content = $"Happy {((TextBox)e.OriginalSource).Text}";
}
}
You don't do anything with the text from your textbox in your handler but I have some code there proves you could get at that from mainwindow if you wanted.
My viewmodel:
public class MainWindowViewModel : INotifyPropertyChanged
{
private string inputString;
public string InputString
{
get { return inputString; }
set
{
inputString = value;
OutputString = $"{inputString.Length} characters entered";
RaisePropertyChanged();
}
}
private string outputString;
public string OutputString
{
get { return outputString; }
set
{
outputString = value;
RaisePropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Usercontrol1 just has a textbox:
<Grid>
<TextBox Text="{Binding InputString, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
As you type in that textbox, the text is transferred to the bound property in my viewmodel. That hits the code in my setter. This in turn sets OutputString which is bound to my textblock.
Text changes in both my label and textblock as I type.
Here's a link to my sample on onedrive
https://1drv.ms/u/s!AmPvL3r385QhgpgOPNKPs-veFJ2O3g
The main problem here is that your View1 class is subscribing to an event on a new MainWindow instance, not the MainWindow instance created by your application on start.
Since your MainWindow class has a reference to your View1 class (a named member "ViewOne") you should just change it from the MainWindow class.
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
ViewOne.ViewOneLabel.Content = "Happy";
}
Get rid of the chenagedText event handler and all the code in the View1.xaml.cs... you don't need it.
Note: I am hoping that you are just playing around and learning here... there is no way I would condone building a WPF application in this way.
You could only use the event of the MainPage. I recomment you to add a Property to the UserControl. In my case I call it Text.
public string Text
{
set { ViewOneLabel.Content = value; }
}
In the MainWindow use the Property within the TextChanged Event.
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
OpenView1.Text = TextBox.Text;
}
You are creating a new instance of MainWindow in your UserControl. What you want to do is to hook up an event handler to the instance that you actually see on the screen. You can get a reference to this one using the Window.GetWindow method:
public partial class View1 : UserControl
{
public View1()
{
InitializeComponent();
Loaded += (s, e) =>
{
Window mainWindow = Window.GetWindow(this) as MainWindow;
if(mainWindow != null)
mainWindow.changedText += newWindow_ChangeText;
};
}
void newWindow_ChangeText(object sender, EventArgs e)
{
ViewOnelabel.Content = "Happy";
}
}
I got an Problem with updating the text in a Textbox. I got this MainWindow:
<Window x:Class="TestDatabinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10,10,10,10"/>
<Button Grid.Row="1" Content="Click me" Margin="10,10,10,10" Click="Button_Click"></Button>
<Button Grid.Row="2" x:Name="a1" Content="ShowText" Margin="10,10,10,10" Click="a1_Click" ></Button>
</Grid>
Now the cs-file for this MainWindow looks like:
using System.Windows;
namespace TestDatabinding
{
public partial class MainWindow : Window
{
MainWindowViewModel mwvm;
public MainWindow()
{
InitializeComponent();
mwvm = new MainWindowViewModel();
this.DataContext = mwvm;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
mwvm.ChangeText();
this.DataContext = mwvm;
}
private void a1_Click(object sender, RoutedEventArgs e)
{
mwvm.showText();
}
}
}
And last but not least the ViewModel Class:
using System.ComponentModel;
using System.Windows;
namespace TestDatabinding
{
class MainWindowViewModel
{
public event PropertyChangedEventHandler PropertyChanged;
private string text;
public string Text
{
get { return this.text; }
set
{
this.text = value;
OnPropertyChanged("Text");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
public void ChangeText()
{
this.Text = "Hey paadddyy";
}
public void showText()
{
MessageBox.Show(Text);
}
}
}
I didn´t implement ICommands, because this is a simple test.
Now the Button's work correctly but the Textbox Text didn´t get updated.
Any suggestions what i can do? I only want to display "Hey paadddyy" when I click the first Button. After I press the second Button and then the first the MessageBox shows "Hey paadddyy" but the Textbox text didn´t get updated :(
Thank you for every hint ;)
Your MainWindowViewModel does not implement INotifyPropertyChanged. It needs to look like that:
class MainWindowViewModel: INotifyPropertyChanged
you define the event but does not implement the interface
It need to implement INotifyPropertyChanged
I suggested that if you want to do something with Notify Property. Another easy way is to apply Caliburn.Micro Framework to your project.
Follow this link.
Overview
I have a WPF application written in C# .NET 4.0. There are a number of buttons in this project. Currently, every EventHandler for the button click events calls the same method, with a different valued parameter. As this is all done in C# code, it is rather unwieldy and involves a lot of copy/paste.
I'd much rather use a Command, rather than a bunch of EventHandlers, as it keeps my code cleaner.
Problem
No matter what I do, I cannot get the XAML to accept the new command:
<Window.CommandBindings>
<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
</Window.CommandBindings>
The above code has an error: "CommandConverter cannot convert from System.String". This error exists on the Command="ButtonClick".
Research/Attempts
I've tried everything I can think of to make this work to no avail. I've looked at at least 30 different blog posts/tutorials/etc. on how to properly do this, so I don't have an actual list for you. I saw some people using the Binding keyword, so I attempted: Command="{Binding ButtonClick}", but apparently that's not allowed inside a CommandBinding section. I have also tried Command="{x:Static ButtonClick}", but that doesn't work either.
As for the "ButtonClick" itself, I have tried several possible values there. "ButtonClick" is an arbitrary text string that does not correspond to any class/method/variable. My original understanding of this parameter was for the value to be simply an identifying string. I have also tried using an actual method in the same class "ButtonClick_Executed". I have also tried using a class name which implements ICommand (Commands), as well as a method inside that class (Commands.ButtonClick_Executed).
For reference, I also tried doing this in the codebehind as per WPF: Binding to commands in code behind, but I couldn't make that work either.
Code
Code is abridged to what is relevant. From what I understand, the Button's Command parameter needs to match the CommandBinding's Command value. I have not added this in yet, since I can't even get the CommandBinding to work. All code is in the same namespace, in a single project.
MainWindow.xaml:
<Window x:Class="T9Messager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="540">
<Window.CommandBindings>
<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
</Window.CommandBindings>
<Grid Margin="0,0,0,0">
<Button x:Name="Button1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="165" Height="113">
<TextBlock HorizontalAlignment="Center" TextAlignment="Center" FontSize="18" FontWeight="Bold">1</TextBlock>
</Button>
... More buttons ...
</Grid>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window, IObserver<Model>
{
private Controller controller;
private IDisposable Unsubscriber;
public MainWindow()
{
Model model = new Model();
Controller controller = new Controller(model);
this.controller = controller; // MainWindow view = new MainWindow(c);
Unsubscriber = model.Subscribe(this);
InitializeComponent();
}
// This is the method I want to run
public void ButtonClick_Executed(object sender, EventArgs ev)
{
Console.WriteLine("Command Executed");
}
// I want to avoid having a bunch of these
private void Button_Click_1(object sender, RoutedEventArgs e)
{
controller.HandleButtonClick('1');
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
controller.HandleButtonClick('2');
}
... More ButtonClick Events ...
public void OnCompleted()
{
Unsubscriber.Dispose();
}
public void OnError(Exception error)
{
throw new NotImplementedException();
}
public void OnNext(Model value)
{
tb_text.Text = value.text;
}
}
Commands.cs:
public class Commands : ICommand
{
public Commands()
{
CommandBinding ButtonClickBinding = new CommandBinding(ButtonClickCommand);
CommandManager.RegisterClassCommandBinding(typeof(Commands), ButtonClickBinding);
}
private RoutedUICommand ButtonClick = new RoutedUICommand("ButtonClick", "ButtonClick", typeof(Commands));
public RoutedCommand ButtonClickCommand
{
get { return ButtonClick; }
}
// Getting any of the following 3 methods to execute would be fine
public static void test()
{
}
public void Execute(object parameter)
{
ButtonClick_Executed(null, null);
}
public void ButtonClick_Executed(object sender, EventArgs ev)
{
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
}
Any and all help is greatly appreciated. Please let me know if you require any additional information.
Update
I have attempted the answer proposed by Herdo. The new error I got was The namespace prefix "T9Messager" is not defined. After research, my XAML now opens like this:
<Window x:Class="T9Messager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:T9Messager="clr-namespace:T9Messager"
Title="MainWindow" Height="600" Width="540">
This seems to have fixed that particular issue, but now it looks as if the XAML is completely ignoring the Command parameter. Command="T9Messager:Commands.ButtonClick" creates the error Value cannot be null. Parameter name: value.
This ButtonClick is a String:
<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
You need to write it as a member of the class (note that you need to add the namespace in the window declaration):
<Window xmlns:t9m="clr-namespace:T9Messager"
...>
<CommandBinding Command="t9m:Commands.ButtonClick"
Executed="ButtonClick_Executed" />
In my code, I removed the "x:Static" from 'Command="{x:Static ButtonClick}"' and worked.
Intention is to get and handle Routed Events from child Window. I cannot (read: do not want to) use direct routing as there are more elements between (a Command).
The following example demonstrates that Event Routing is not working from one Window to second Window.
Child window XAML:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Button Content="Raise Routing Event" HorizontalAlignment="Left" Margin="50" VerticalAlignment="Top"
Width="150" Click="RaiseRoutedEvent" />
</Grid>
Raise Event Code:
using System.Windows;
namespace WpfApplication1
{
public partial class Window1
{
private static readonly RoutedEvent ChildWindowEvent = EventManager.RegisterRoutedEvent("ButtonClicked",
RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Window1));
public Window1()
{
InitializeComponent();
}
public event RoutedEventHandler ButtonClicked
{
add { AddHandler(ChildWindowEvent, value); }
remove { RemoveHandler(ChildWindowEvent, value); }
}
private void RaiseRoutedEvent(object sender, RoutedEventArgs e)
{
RoutedEventArgs eventArgs = new RoutedEventArgs(ChildWindowEvent);
RaiseEvent(eventArgs);
}
}
}
Main window:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525" wpfApplication1:Window1.ButtonClicked="HandleRoutedEvent">
<Grid>
<Button Content="Open new window" HorizontalAlignment="Left" Margin="50" VerticalAlignment="Top"
Width="150" Click="OpenNewWindow" />
</Grid>
</Window>
Window which should handle the routed event:
using System.Windows;
namespace WpfApplication1
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void OpenNewWindow(object sender, RoutedEventArgs e)
{
Window1 window1 = new Window1();
window1.ShowDialog();
}
private void HandleRoutedEvent(object sender, RoutedEventArgs e)
{
MessageBox.Show("This message is shown from the Main Window");
}
}
}
The event is raised from Window1 but the MainWindow.HandleRoutedEvent does not hit its break point. Why?
Routed Events travel along the visual tree. A top-level window is a visual tree root and is not part of its owner's visual tree. Therefore, any events which bubble up from within a child window will not propagate up to the owner window.
As an aside, I noticed a couple issues in your example code. In your xaml, you register a handler with attached event syntax, but you have declared an instance event. If you want to implement an attached event, you will need these members:
public static readonly RoutedEvent ButtonClickedEvent = EventManager.RegisterCrossWindowRoutedEvent(
"ButtonClicked",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(ChildWindow));
public static void AddButtonClickedHandler(UIElement target, RoutedEventHandler handler)
{
target.AddHandler(ButtonClickedEvent, handler);
}
public static void RemoveButtonClickedHandler(UIElement target, RoutedEventHandler handler)
{
target.RemoveHandler(ButtonClickedEvent, handler);
}
If you intended to have an instance event, the event name should correspond with the name provided when registering the routed event ("ButtonClicked").
I have a strange problem in my project. There are pages made from usercontrol and menu bar (also usercontrol).
Here is my usercontrol that contains few buttons
public partial class UpperBar : UserControl
{
public UpperBar()
{
InitializeComponent();
}
public event EventHandler EventbtClicked;
private void btConnect_Click(object sender, System.Windows.RoutedEventArgs e)
{
EventbtClicked(this, e);
}
}
I added this in my page as follows:
<local:UpperBar VerticalAlignment="Top" Grid.Row="0" Height="78" Grid.ColumnSpan="3" Margin="0,2,0,0"/>
And in my page tried to call event:
public PageStatus()
{
InitializeComponent();
Plc.ExecuteRefresh += new EventHandler(RefreshLeds);
UpperBar.EventbtCliced += new EventHandler(UpperBatButtonClick);
}
protected void UpperBarButtonClick(object sender, EventArgs e)
{
//do something
}
But I can't access my event using this UpperBar.EventbtCliced, why ?
You need to access the instance of your class UpperBar in PageStatus, not the class UpperBar itself!
The easiest way for you here:
Name your UpperBar in your XAML, example:
<local:UpperBar x:Name="_myBar" x:FieldModifier="private"/>
Then use this instance in your PageStatus.xaml.cs:
public partial class MainWindow : Window {
public MainWindow()
{
InitializeComponent();
_myBar.EventbtClicked += new EventHandler(UpperBarButtonClick);
}
protected void UpperBarButtonClick(object sender, EventArgs e)
{
//do something
}
}
Now if you are working seriously in WPF, you should really learn about Databinding and MVVM, catching event this way is not the best way to do it at all.
You should use Custom Command (RoutedUICommand) rather than bubbling event from user control.
here are some steps to follow in contrast to your approach:
1: create class myCustomCommand.
namespace WpfApplication1
{
public class myCustomCommand.
{
private static RoutedUICommand _luanchcommand;//mvvm
static myCustomCommand.()
{
System.Windows.MessageBox.Show("from contructor"); // static consructor is called when static memeber is first accessed(non intanciated object)
InputGestureCollection gesturecollection = new InputGestureCollection();
gesturecollection.Add(new KeyGesture(Key.L,ModifierKeys.Control));//ctrl+L
_luanchcommand =new RoutedUICommand("Launch","Launch",typeof(myCustomCommand.),gesturecollection);
}
public static RoutedUICommand Launch
{
get
{
return _luanchcommand;
}
}
}
}
In the xaml of UserControl:
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:CustomCommands="clr-namespace:WpfApplication1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.CommandBindings>
<CommandBinding Command="CustomCommands:myCustomCommand.Launch" Executed="CommandBinding_Executed">
</CommandBinding>
</UserControl.CommandBindings>
<Grid >
<TextBox Name="mytxt" Height="30" Width="60" Margin="50,50,50,50" ></TextBox>
<Button Name="b" Height="30" Width="60" Margin="109,152,109,78" Command="CustomCommands:ZenabUICommand.Launch"></Button>
</Grid>
Now in User control code
Handle command_executed
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
mytxt.Text = "invoked on custom command";
}
}
}