In my WPF app I want to show a popup when I click a button.
If I click outside the popup, I want the popup to be closed. I can accomplish this by setting StaysOpen=False on the popup.
But when I click outside the popup, I want WPF to ignore the initial click that closes the popup. For example, if I click outside the popup on another button, I don't want that button to execute the click method.
How can I make WPF ignore the click outside the popup while it's open?
Here is some sample code. The popup opens when I click the "Popup" button, and it closes when I click outside. But I can click the "PrintMessage" button while the popup is open and its click event will fire. I would like its click event not to fire.
<Window x:Class="Test.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">
<Window.Resources>
<Popup x:Key="pop" StaysOpen="False" Placement="MousePoint">
<UniformGrid Background="Red">
<Button>Btn1</Button>
<Button>Btn2</Button>
</UniformGrid>
</Popup>
</Window.Resources>
<UniformGrid>
<Button Click="Popup_Click">Popup</Button>
<Button Click="PrintMessage_Click">PrintMessage</Button>
</UniformGrid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Popup_Click(object sender, RoutedEventArgs e)
{
Popup pop = (Popup)Resources["pop"];
pop.IsOpen = true;
}
private void PrintMessage_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Test");
}
}
Related
I want to manually control the behavior of InputPane to prevent it from showing or hiding automatically.
In my page that I put its image top, I want to InputPane show as user navigate to the page and keep showing until he/she clicks on specified button and prevent it from hiding if user clicks anywhere else in the page.
Also I want to InputPane remain hidden even if user clicks on TextBox.
I already know that there are TryShow() and TryHide(), but i can't revent auto showing and hiding.
The easy way to control it is by controlling focus of your TextBox. If you set IsTabStop on the TextBox to false - it won't take focus and so the SIP won't show up. If it already has focus - you'll need to move it out. If you want to display the SIP - focus the TextBox. Note that for performance reasons and also to prevent user confusion - it might make sense to use a TextBlock instead of a TextBox when the control should not be editable.
XAML
<Page
x:Class="App18.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App18"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<TextBox
x:Name="myTextBox"
IsTabStop="False"
AcceptsReturn="True"
VerticalAlignment="Stretch"
TextChanged="MyTextBox_OnTextChanged"/>
<Button
x:Name="myButton"
Grid.Row="1"
Click="ButtonBase_OnClick">Edit</Button>
</Grid>
</Page>
C#
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace App18
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
myTextBox.IsTabStop = true;
myTextBox.Focus(FocusState.Programmatic);
}
private void MyTextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (myTextBox.Text.ToLower().Contains("done"))
{
myTextBox.IsTabStop = false;
myButton.Focus(FocusState.Programmatic);
}
}
}
}
I am making a window with
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent"
WindowStartupLocation="CenterScreen"
ResizeMode="NoResize"
then I made a button other to move the window, using this.DragMove();, I put it into some event: MouseDown (of the button), LeftbutonDown (of the button) and LeftbutonDown (of the form), but still can not move the form.
My function:
private void btCurDate_MouseDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
(the button are defined Click event to do something else). My running form:
I am having a simple WPF Ribbon Window using RibbonControlsLibrary.
In this Window I am having a RibbonComboBox which contains an Button Element. My intent is to close RibbonComboBox' dropdown once the Button is clicked. I do not want manipulate the IsOpen property of the RibbonComboBox, since the Button should be reused for different purposes. My idea was to handle the MouseDown event of the button and then set e.Handled to false
The XAML looks like this
<ribbon:RibbonWindow x:Class="WpfRibbonApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
xmlns:my="clr-namespace:WpfRibbonApplication3"
Title="MainWindow"
x:Name="RibbonWindow"
Width="640" Height="480">
<ribbon:Ribbon>
<ribbon:RibbonTab Header="Home">
<ribbon:RibbonGroup Header="Group1">
<ribbon:RibbonComboBox>
<ribbon:RibbonGallery>
<ribbon:RibbonGalleryCategory>
<ribbon:RibbonGalleryItem>
<my:CustomButton Content="Test" />
</ribbon:RibbonGalleryItem>
</ribbon:RibbonGalleryCategory>
</ribbon:RibbonGallery>
</ribbon:RibbonComboBox>
</ribbon:RibbonGroup>
</ribbon:RibbonTab>
</ribbon:Ribbon>
</ribbon:RibbonWindow>
The code behind looks as follows:
public CustomButton()
{
// Insert code required on object creation below this point.
AddHandler(MouseDownEvent,(RoutedEventHandler)Button_MouseDown,true);
}
private void Button_MouseDown(object sender, RoutedEventArgs e)
{
Console.WriteLine(string.Format("MouseDownEvent, e.Handled = {0}", e.Handled));
e.Handled = false;
}
The event gets fired but the Ribbon dropdown closes only when pressing the button the second time. Interestingly, the second time I press the button the MouseDown event handler does not get invoked. Can someone give me some hints on how to achieve closing of the ribbon on the first click in a clean manner?
You can give your RibbonComboBox a name, let's say x:Name="comboBox", then in the code behind in the mouse down event handler, you can simply do: comboBox.IsDropDownOpen = false;
I want to perform a particular action when user cancels my dialog by clicking the close button (red X button)
and not when the form is closing because of some other operation. How i can determine whether the
private void Window_Closing(object sender, CancelEventArgs e)
event is raised by the button ?
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="60" Width="284" WindowStartupLocation="CenterScreen"
BorderBrush="#FFCCCCCC"
BorderThickness="2"
Background="#FFE0E0E0"
WindowStyle="SingleBorderWindow"
ShowInTaskbar="False" ResizeMode="NoResize" Closing="Window_Closing">
public MainWindow()
{
InitializeComponent();
this.Closing+=new System.ComponentModel.CancelEventHandler(MainWindow_Closing);
}
private void MainWindow_Closing(object sender, EventArgs e)
{
MessageBox.Show("salman");
}
My question is what are the other ways of closing this window? My understanding is the sender is always going to be the Window.
I would do the following - for all buttons or user based close - set a public property on the Window (something like bool ClosedByUser) and set it to "true" and then call Close().
For other cases (such as closing by clicking "X"), the property is by default set to false. In the closing event handler, use the property to make the decision.
Please note: There are other questions and answers similar to this on StackOverflow.
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
}