ShowDialog in WPF - c#

When I make two calls for ShowDialog in WPF the first window open normally, after closing it the second one doesn't appear.
<Application
x:Class="Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="App_OnStartup">
</Application>
private void App_OnStartup(object sender, StartupEventArgs e)
{
var windowA = new WindowA();
windowA.ShowDialog();
var windowB = new WindowB();
windowB.ShowDialog();
}
WindowA:
<Window x:Class="Test.WindowA"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowA" Height="129.452" Width="313.356">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="139,54,0,0"/>
</Grid>
</Window>
public partial class WindowA : Window
{
public WindowA()
{
InitializeComponent();
}
}
WindowB:
<Window x:Class="Test.WindowB"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowB" Height="221.918" Width="300">
<Grid>
<RadioButton Content="RadioButton" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="124,63,0,0"/>
</Grid>
</Window>
public partial class WindowB : Window
{
public WindowB()
{
InitializeComponent();
}
}

In WPF you can specify when application shuts down and by default Application.ShutdownMode is OnLastWindowClose which means that when last Window is closed applications shuts down and in your case first Window is also last. When you open and close first Window your application shuts down and that's why you don't see second Window. You would need to change ShutdownMode to OnExplicitShutdown
<Application ... ShutdownMode="OnExplicitShutdown"/>
but this means that even when you close all your windows application is still running so you have to explicitly call Application.Shutdown() to shutdown your application, for example when main window is closed.

ShowDialog() function invokes the window modally. Which means code after windowA.ShowDialog(); will not execute until that window is closed.

Related

Setting WindowStyle and AllowTransparency in usercontrol

I have a simple usercontrol in my MainWindow. I am trying to create a simple Window Template that is easily protable. I have a usercontrol and this seems to serve my purpose so far well...kinda...
If I set AllowTransparency and WindowStyle in the usercontrol the project compiles successfully but in the MainWindow in the control I get Object Not Set to Instance of... And the entire control is underlined. All good if I set in MainWindow. I can live with this but not the desired result.
xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cntl="clr-namespace:Rtg"
Title="MainWindow" Height="400" Width="525">
<!-- if I add windowstyle and allowtransparency here all good -->
<Grid>
<cntl:test1 WinTitle="test window framing">
<cntl:test1.PlaceHolder1>
<Grid Background="Orange">
<TextBox BorderBrush="Transparent" Text="Content in placehoder:" Height="35" Width="175" Margin="0,10,270,0" Background="Transparent" FontSize="16" ></TextBox>
<Button Width="100" Height="35" Content="click me" FontSize="16"></Button>
</Grid>
</cntl:test1.PlaceHolder1>
</cntl:test1>
</Grid>
</Window>
C#
public test1() {
Window win = Application.Current.MainWindow;
win.WindowStyle = System.Windows.WindowStyle.None;
win.AllowsTransparency = true;
InitializeComponent();
ctrTest2.Title = WinTitle;
}
Been web developing for the last 15 years WPF is somewhat pretty new to me.
Is this Normal Behavior for WPF?
Is there away Around This so I can set window Properties in the usercotrol?
public test1() {
InitializeComponent();
ctrTest2.Title = WinTitle;
//Need to do it after Initialization
Window win = Application.Current.MainWindow;
win.WindowStyle = System.Windows.WindowStyle.None;
win.AllowsTransparency = true;
}
A more "WPF" way of handling it would be to create a ViewModel and Bind the properties
public class MainViewModel : INotifiyPropertyChanged{
private WindowStyle _windowStyle;
public WindowStyle WinStyle {
get{
return _windowStyle;
}
set{
_windowStyle = value;OnPropertyChanged("WinStyle");
}
}
}
And in the XAML
WindowStyle="{Binding Path=WinStyle}"
Found the Error. I was sending one of my functions an int so that I knew which window was loading. Because no windows or variables are initialized when the app is not running, Visual Studio's decided that my integer was out of the bounds of the array. Adding a simple if statement around the above code fixed all issues. Picky Picky WPF.
Kevin, I was unsure of what you meant by View Model. After Reading some the xaml.cs or UserControl in my case would be the ViewModel correct?
here is my fix.
if (LoadingWindow > -1 && Application.Current.Windows.Count > LoadingWindow) {
// Load Window
}

Textbox created in WPF is not editable at run time

I am creating a WPF Window in which I have text boxes. However, when I run the project in Debug mode, (F5), I am not able to edit the text boxes that I created, nor am I able to choose from the listbox that I created. I googled, found that WPF and Win32 need to communicate to accept keyboard input, and got these 3 lines :
Window w = new Window1();
System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(w);
w.Show();
However, I am new to C# and hence I have absolutely no idea where to insert this C# code. I added the System.Windows.Forms and WindowsFormIntegration references to my project.
The window I am designing will be the first window that will appear at the launch of the application, hence I need the textboxes in this window to be editable without launching another window. Kindly guide me.
Edit : This is my XAML code:
<Window x:Name="Window1" x:Class="Myproject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Risk Assessment"
Height="741" Width="1216.091">
<GroupBox x:Name="GroupBox1">
<Grid>
<TextBox x:Name="Length" IsReadOnly ="False" IsEnabled="True" />
</Grid>
</GroupBox>
</Window>
This is my C# code:
namespace Myproject
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
Edit 2: I modified the first line in the App.Xaml code like this :
<Application x:Class="Myproject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
And in the App.Xaml.cs I added this snippet:
private void Application_Startup(object sender, StartupEventArgs e)
{
MainWindow win = new MainWindow();
ElementHost.EnableModelessKeyboardInterop(win);
win.Show();
System.Windows.Threading.Dispatcher.Run();
}
But still no luck. Where am I going wrong?
Try to change your Application.xaml to include the StartupUri:
<Application x:Class="Myproject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"
>
Remove all the startup code you had in the cs file.
Or
Change your cs code to this:
Window1 window1 = new Window1();
this.ShutdownMode = ShutdownMode.OnMainWindowClose;
this.MainWindow = window1;

Weird Unload Behaviour - WPF Window

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
}

Prevent window from spanning multiple monitors

Is there any simple way to prevent WPF windows from spanning multiple monitors in a dual-monitor setup? With "simple" I mean without writing code-behind that measures the monitor size and assigns a width to the Window.
I would prefer if a window uses only the part available on the current monitor (where "current" means the monitor with the currently focused window). It is OK if the user resizes the window such that it covers both monitors, but at the time when the window opens it shall stay on a single monitor.
Here is an example:
MainWindow.xaml:
<Window x:Class="MultiMonitorTest.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="Open Window"
Height="70"
HorizontalAlignment="Left"
Margin="165,147,0,0"
Name="button1"
VerticalAlignment="Top"
Width="179"
Click="button1_Click" />
</Grid>
</Window>
MainWIndow.xaml.cs:
using System.Windows;
namespace MultiMonitorTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Window2 win = new Window2();
win.ShowDialog();
}
}
}
Window2.xaml:
<Window x:Class="MultiMonitorTest.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2"
SizeToContent="WidthAndHeight">
<Grid>
<TextBox x:Name="txt"
Margin="10"
Background="LightPink"
AcceptsTab="True"
AcceptsReturn="True"
TextWrapping="Wrap"/>
</Grid>
</Window>
Window2.xaml.cs:
using System.Windows;
namespace MultiMonitorTest
{
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
txt.Text = new string('x', 1000);
}
}
}
When clicking the "Open window" button, the new window opens across two monitors. I would prefer if Window2 stayed completely within the current monitor.
Well, you could use the same width, height (and perhaps position) as the parent window on the second one. Without additional code, I don't think you can really force the window to span across two monitors. You can however, with limited code start it on one instead of two.
WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; // in your Window Xaml
//and combine with
Rectangle workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea; // Reference System.Windows.Forms and set left, top, width and height accordingly.
This is the best you can do I think without having to write 'large amounts' of code (this will center it to the working area of the primary screen). If you really want to limit your window to span across multiple monitors is of course possible, but requires some work.
A good starting point would be the WindowInteropHelper class.

c# Messagebox for touchscreen

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

Categories

Resources