Handle same events from different windows - wpf

I have a WPF project with two windows, the first window firing events and have it's own event handlers, the other window will fire the same events, any idea how to use handlers in first window to handle events in second window ?

thanks to #Cody Gray , #keyboardP and to this useful article http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx
Here's a code snippet to demonstrate the answer:
first step add a new subclass :
using System.Windows;
namespace WpfApplication
{
public class Subclass : Window
{
//Event handlers,functions or any potential reused code
}
}
Second step: go to window1.xaml.cs
namespace WpfApplication
{
public partial class Window1 : Subclass
{
public Window1()
{
InitializeComponent();
}
}
}
Third step: change the Xaml code for window1 as below:
<src:Subclass
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:WpfApplication"
Title="Window1" Height="350" Width="525">
</src:Subclass>
Finally do 2nd & 3rd steps for window2

A simple sample of what i was proposing in first place:
<Window x:Class="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>
<Window Loaded="Window_Loaded"/>
<Window Loaded="Window_Loaded"/>
</Grid>
</Window>
Look how both windows share the event handler:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Whatever
}
}
At this point you should ask yourself if you really needed two windows, or any other container control could be enough.

Related

RoutedCommands bound by sub elements never fire

I'm trying to get my head around RoutedCommands in WPF. I like how they decrease coupling between different UI elements and the models but I can't seem to make the bindings work for custom controls that are children to the window. I guess this will be some easy creds for any of you WPF wizards out there! :-)
Here's some example code that can be tried out:
The routed command:
using System.Windows.Input;
namespace Wpf.RoutedCommands
{
public static class Commands
{
public static readonly RoutedCommand SayHi = new RoutedCommand();
}
}
Main window XAML:
<Window x:Class="Wpf.RoutedCommands.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Wpf.RoutedCommands"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<!-- uncommenting the below makes it work but introduces coupling -->
<!--<Window.CommandBindings>
<CommandBinding Command="{x:Static local:Commands.SayHi}" Executed="cmdSayHi" CanExecute="cmdCanSayHi"></CommandBinding>
</Window.CommandBindings>-->
<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Bottom" Content="Say Hi!" Command="{x:Static local:Commands.SayHi}" />
<local:Greeter x:Name="Greeter" />
</DockPanel>
Main window code:
using System.Windows.Input;
namespace Wpf.RoutedCommands
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
// these two will be used if you uncomment the command bindings in XAML
private void cmdCanSayHi(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = true;
private void cmdSayHi(object sender, ExecutedRoutedEventArgs e) => Greeter.SayHi();
}
}
Custom control ("Greeter") XAML:
<UserControl x:Class="Wpf.RoutedCommands.Greeter"
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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.RoutedCommands"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.CommandBindings>
<CommandBinding Command="{x:Static local:Commands.SayHi}" Executed="cmdSayHi" CanExecute="cmdCanSayHi"/>
</UserControl.CommandBindings>
<Grid>
<Label x:Name="Label" />
</Grid>
Greeter code:
using System.Windows.Input;
namespace Wpf.RoutedCommands
{
public partial class Greeter
{
public Greeter()
{
InitializeComponent();
}
private void cmdSayHi(object sender, ExecutedRoutedEventArgs e) => SayHi();
private void cmdCanSayHi(object sender, CanExecuteRoutedEventArgs e) => e.CanExecute = true;
public void SayHi() => Label.Content = "Hi!";
}
}
If you create a WPF project and use the above you will see that the button in main window is disabled. Debugging it shows that the Greeter.cmdCanSayHi method never gets called.
If you uncomment the dormant XAML in main window everything works. So: Why can I bind to commands from the window but not from its child controls? Is it to do with rendering timing or something?
A RoutedCommand searches the visual tree from the focused element and up for an element that has a matching CommandBinding and then executes the Execute delegate for this particular CommandBinding.
Your UserControl is located below the Button in the element tree.

How to enable DesignTime data in Visual Studio with Unity 4 and MvvmLight

I'm trying to get my head around WPF, Unity and MvvMlight (galasoft). So far my little set up works. If I run my application the label is filled with a random name generated by my DataService. (small victory getting all moving parts to work)
But in the design view of Visual Studio the label remains empty. How do i convince VisualStudio to render some 'design time' data in my label?
I'm using: Visual Studio Premium 2013, Unity 4.0.1, MvvmLight 5.2, .net 4.5
App.xaml.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IDataService, DataService>();
container.RegisterType<IMainViewModel, MainViewModel>();
MainWindow mainWindow = container.Resolve<MainWindow>();
mainWindow.Show();
base.OnStartup(e);
}
}
In App.xaml I have not defined the StartUpUri
MainWindow.xaml
<Window x:Class="UnityMvvmTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="500">
<Grid>
<Label x:Name="myLabel" Content="{Binding MyText}"/>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public MainWindow(IMainViewModel theViewModel)
: this()
{
this.DataContext = theViewModel;
}
}
MainViewModel.cs
public class MainViewModel : ViewModelBase, IMainViewModel
{
private readonly IDataService _dataService;
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
if (IsInDesignMode)
{
// Code runs in design time data.
MyText = "Design Data";
}
else
{
// Code runs "for real"
MyText = _dataService.GetName();
}
}
public string MyText { get; set; }
}
I found a method, using hints from https://stackoverflow.com/a/3380895/249845
I created a second (flat) implementation of IMainVieModel in a separate namespace: UnityMvvmTest.ViewModel.Design. This implementation has no logic, it just fills the properties so the designer has some data to display.
This implementation is used in design time, since it is specified as the DesignTime DataContext. (with xmlns:d, xmlns:mc and xmlns:vm). The mc-namespace is needed to hide the d-namespace during runtime, see why.
The result is 5 extra lines in the Xaml, an extra (almost empty) implementation of IMainViewModel. And an extra (empty) constructor in code behind, instead of a constuctor that test for IsInDesignMode. This isn't a big deal, since unity will pick the constructor with the most parameters it can resolve.
MainWindow.xaml
<Window x:Class="UnityMvvmTest.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"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:UnityMvvmTest.ViewModel.Design"
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type=vm:MainViewModel}"
mc:Ignorable="d"
>
<Grid>
<Label x:Name="myLabel" Content="{Binding MyText}" />
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
// Contructor used in DesignTime
public MainWindow()
{
InitializeComponent();
}
//Constructor used by Unity
public MainWindow(IMainViewModel theViewModel)
: this()
{
this.DataContext = theViewModel;
}
}
MainViewModel.cs (design time implementation)
namespace UnityMvvmTest.ViewModel.Design
{
public class MainViewModel : IMainViewModel
{
public MainViewModel()
{
MyText = "my Design time data";
}
public string MyText { get; set; }
}
}

How to display User Control Property in visual studio properties browser

Good afternoon,
I am using WPF.
I have the following class:
public partial class UserControl1 : UserControl
{
private TimeSpan timeMinutesInterval;
public TimeSpan TimeMinutesInterval
{
get { return timeMinutesInterval; }
set { timeMinutesInterval = value; }
}
public UserControl1()
{
this.InitializeComponent();
}
private void TimePickerNew_Loaded(object sender, RoutedEventArgs e)
{
}
}
What do I need for the property TimeMinutesInterval appears in the visual studio properties browser?
Thank U
Once you add the control to another control/window/etc., you can see the property under the Miscellaneous section of the properties window for that added control. Is that what you were looking for?
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication5"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 TimeMinutesInterval="0:5:0" />
</Grid>

Inheriting from custom window in WPF

I have a custom window in WPF which I want to use as a base window for other windows.
When I tried to inherit it, I wrote in the XAML:
<my:MyWindow x:Class="NewWindow"
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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:my="clr-namespace:MyNamesapce;assembly=MyAssembly"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
In the .cs code I wrote:
namespace SomeOtherNamespace
{
public partial class NewWindow: MyWindow
{
internal NewWindow(Control ctrl) : base(ctrl)
{
InitializeComponent();
this.ResizeMode = System.Windows.ResizeMode.NoResize;
}
}
}
But then I got the error:
cannot be the root of a XAML file because it was defined using XAML.
What am I doing wrong and how can I fix it?
If what you are trying to achieve is setting ResizeMode to NoResize in every window you could use a style like this:
<Style TargetType="Window" x:Key="windowStyle">
<Setter Property="ResizeMode" Value="NoResize" />
</Style>
Put this style in a ResourceDictionary and make it be the window style:
Style="{StaticResource windowStyle}"
But if you want to go further you'll have to make a new class inheriting from Window
public class MyWindow : Window
{
public MyWindow()
{
this.ResizeMode = ResizeMode.NoResize;
}
}
Now you are able to instanciate a new MyWindow
<mn:MyWindow x:Class="Project.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mn="clr-namespace:MyControls"
Height="300" Width="300">
</mn:MyWindow>
Be aware the class that will be the "code behind" of this new window need to inherit from your new MyWindow class as below:
namespace Project
{
public partial class Window1 : MyControls.MyWindow
{
public Window1()
{
InitializeComponent();
}
}
}

Implement short cut keys in Wpf application

I am new to wpf application and I am working on application and i have created a menu Now i want to function menu items event on short key ctrl+o, ctrl+n etc. How can i do it.please give me in details.
You can so it in the following way....
In Xaml file
<Window x:Class="FocusDemo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FocusDemo"
Title="Window1" Height="300" Width="300">
<Window.CommandBindings>
<CommandBinding
Command=
"{x:Static
local:Window1.CustomRoutedCommand}"
Executed="ExecutedCustomCommand"
CanExecute="CanExecuteCustomCommand" >
</CommandBinding>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding
Command=
"{x:Static
local:Window1.CustomRoutedCommand}"
Key="S"
Modifiers="Control"/>
</Window.InputBindings>
<Grid>
<!--Your Controls-->
</Grid>
</Window>
In the Code behind file
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public static RoutedCommand CustomRoutedCommand = new RoutedCommand();
public Window1()
{
InitializeComponent();
}
#region
public void ExecutedCustomCommand(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Ctrl+S");
}
public void CanExecuteCustomCommand(object sender,
CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
#endregion
}
Source : Click here
Please dont forget to mark the answer if its correct
I know it is not exact answer to the question, but probably anybody like me was searching for the way to put ANY keyboard shortcuts to menu items (command buttons) like Alt+O, Alt+N. In this case, you can just put undescore character (_) before the shortcut character in the item name.

Resources