When I place Button in grid and add to is's click action:
this.Close();
It's not working. I want to be able to ask user before exit so I want to use Close(). I don't want to use Application.Shutdown();
How to solve it.
Just tested it and it works fine! I created a new WPF application and a basic window:
<Window x:Class="WpfApplication1.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>
<Button Content="Close" x:Name="closeButton" Click="closeButton_Click" />
</Grid>
</Window>
and then added the following to the code-behind
private void closeButton_Click(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("Are you sure?", "Application", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
this.Close();
}
}
And it works 100%... Can you post more code to see if something else is wrong? What .NET version are you using, etc...
Related
Let's Say I'm making a simple editor in WPF using a TextBox and a Menu with the option "Edit->Undo". My XML is as follows:
<Window x:Class="WpfApp4.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:WpfApp4"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<DockPanel LastChildFill="True">
<Menu Name="menu1" DockPanel.Dock="Top">
<MenuItem Header="_Edit">
<MenuItem Name="menu1_edit_undo"
Header="_Undo"
InputGestureText="Ctrl+Z"/>
</MenuItem>
</Menu>
<Grid>
<TextBox Name="textbox1"/>
</Grid>
</DockPanel>
</Window>
How do I get the Click event for "menu1_edit_undo" to send the Key Stroke "Ctrl-Z" to the TextBox component textbox1 to invoke the undo feature of the textbox?
HEre's what I tried that didn't work:
private void menu1_edit_undo_Click(
object sender, RoutedEventArgs e)
{
var e2 = new KeyEventArgs(
keyboard: Keyboard.PrimaryDevice,
inputSource: PresentationSource.FromVisual(textbox1),
timestamp: 0,
key: Key.LeftCtrl | Key.Z
)
{
RoutedEvent= Keyboard.KeyDownEvent
};
textbox1.RaiseEvent(e2);
}
The WPF TextBox has an Undo method (part of the TextBoxBase base class) that should provide what you need.
Undoes the most recent undo command. In other words, undoes the most recent undo unit on the undo stack.
Instead of attempting to send keystrokes to the control, just call the method on it:
private void menu1_edit_undo_Click(
object sender, RoutedEventArgs e)
{
textbox1.Undo();
}
Ok... I found out you can do it my adding a Reference to System.Windows.Form to you WPF project, and then adding this to the Click handler:
textbox1.Focus();
System.Windows.Form.SendKeys.SendWait("^z");
I am trying to use RoutedCommands in my UserControls, following the example in this article:
https://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/
I defined the RoutedCommand and CommandBindings in the UserControl instead of in the article's example. I am trying to use it in my MainWindow, so that when the Button is clicked, the Command in the UserControl is executed. However, the Button is disabled and the Foo_CanExecute() method is never executed.
<UserControl x:Class="RoutedCommandTest.ViewControl"
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:RoutedCommandTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.CommandBindings>
<CommandBinding
Command="{x:Static local:ViewControl.Foo}"
PreviewCanExecute="Foo_CanExecute"
PreviewExecuted="Foo_Executed"
/>
</UserControl.CommandBindings>
<Grid>
</Grid>
</UserControl>
Here is the code for ViewControl.xaml.cs:
public static readonly RoutedCommand Foo = new RoutedCommand();
void Foo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
void Foo_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("The Window is Fooing...");
}
public ViewControl()
{
InitializeComponent();
}
And here is the code for MainWindow.xaml:
<Window x:Class="RoutedCommandTest.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:RoutedCommandTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:ViewControl/>
<Button Content="Foo" Margin="0 5" Command="{x:Static local:ViewControl.Foo}"/>
</Grid>
</Window>
I would like to know how to fix the issue so that the Button is enabled and the Foo_CanExecute() method is executed when the Button is clicked.
Your command is in a usercontrol, whilst the button is in mainwindow.
Which presumably contains your usercontrol.
Like bubbling and routing events ( which are used to drive them ).
Executed looks for the command bubbling UP the visual tree to the binding.
PreviewExecuted looks for the command tunnelling DOWN the visual tree to the binding.
Since your button is in the parent of the usercontrol I'm not sure whether either bubbling or tunnelling will work.
But tunnelling would be PreviewExecuted And PreviewCanExecute.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.input.commandbinding.previewexecuted?view=netframework-4.8
https://learn.microsoft.com/en-us/dotnet/api/system.windows.input.commandbinding.previewcanexecute?view=netframework-4.8
Routedcommands can be pretty tricky to get right.
One thing you sometimes have to do is to bind commandtarget to tell it where to go look.
eg:
<Grid>
<local:UserControl1 x:Name="UC1" Height="60" Width="100"/>
<Button Content="Foo" TextElement.FontSize="30" Command="{x:Static local:UserControl1.Foo}"
CommandTarget="{Binding ElementName=UC1}"
/>
</Grid>
Works for me.
I have rarely found them useful - this is one of the aspects makes them way less useful than you might at first imagine.
EDIT:
It's perhaps worth mentioning the other thing makes these unattractive compared to a regular icommand. You need to either use a static which means it's only suitable for very generic commands OR you need event handlers which will be in code behind.
On the other hand.
If you're writing something has to work generically with whatever has focus. Like say a text editor with multiple textboxes and you're doing text manipulation. A routed command might be suitable. I have never encountered such a requirement in apps I've worked on though.
I have been trying to modify the behavior of 'Close Window' button from jump list (to show "Are you sure" dialog or minimize a window like in Skype app).
Do you know how to do this?
You need to handle Closing event for your window:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (MessageBox.Show("Are you sure?", "Closing app", MessageBoxButton.YesNo) == MessageBoxResult.No)
{
e.Cancel = true;
}
}
and in xaml:
<Window x:Class="SO_app.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:vm="clr-namespace:VM;assembly=VM"
xmlns:converter="clr-namespace:SO_app.Converters"
xmlns:validation="clr-namespace:SO_app.Validation"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
xmlns:local="clr-namespace:SO_app"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Closing="Window_Closing"><- here you define the handler
I have a simple WPF application with a MainWindow. Set up an unloaded event in the code behind. Set the MainWindow as the startup uri. Unloaded is not triggered when the window is closed. Create a second window - NotMainWindow with a single button click.
In the button click event, call MainWindow. Close MainWindow and unloaded is triggered. Why the difference in behaviour? What I am trying to get at is, how do I get some kind of unloaded event every single time?
<Window x:Class="WpfApplication2.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" Unloaded="Main_Unloaded">
<Grid>
</Grid>
</Window>
private void Main_Unloaded(object sender, RoutedEventArgs e)
{
}
<Window x:Class="WpfApplication2.NotMainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="NotMainWindow" Height="300" Width="300">
<Grid>
<Button Content="Show Main" Height="25" Margin="10" Width="70" Click="Button_Click" />
</Grid>
</Window>
private void Button_Click(object sender, RoutedEventArgs e)
{
MainWindow win = new MainWindow();
win.Show();
}
<Application x:Class="WpfApplication2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="NotMainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
Based on your comments I understand the scenario you're talking about. This is a known issue that unloaded is not called when shutting down the application (e.g. last window is closed).
If you just want to know when the window is closed use the Closing event:
public MainWindow()
{
this.Closing += new CancelEventHandler(MainWindow_Closing);
InitializeComponent();
}
void MainWindow_Closing(object sender, CancelEventArgs e)
{
// Closing logic here.
}
If you want to know when the last window is closed, e.g. your application is shutting down, you should use ShutdownStarted
public MainWindow()
{
this.Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
InitializeComponent();
}
private void Dispatcher_ShutdownStarted( object sender, EventArgs e )
{
//do what you want to do on app shutdown
}
I need a touch enabled message box for a surface 2.0 application. The standard MessageBox.Show() has to be confirmed with a mouse click.
That is not what I want.
I could write a small UserControl, but I wonder if there is something already integrated.
Use MessageDialog class to represents a dialog.
I did it myself, after searching nearly an hour or so ^^
public partial class MsgBoxTouch : SurfaceWindow
{
public TouchBox1()
{
this.InitializeComponent();
}
private void Button_TouchEnter(object sender, TouchEventArgs e)
{
this.Close();
}
}
}
<s:SurfaceWindow x:Class="MsgBoxTouch"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
WindowState="Normal" WindowStyle="None" Width="300" Height="300">
<Grid x:Name="Layout">
<Button Content="OK" Height="50" TouchEnter="Button_TouchEnter">
</Button>
</Grid>
</s:SurfaceWindow>
blip-surface uses a MessageBox user control maybe you can use something similar to that
http://code.google.com/p/blip-surface/source/browse/trunk/Blip/UI/Controls/?r=28