I have two windows in a single application.
The first window has one button. When I click the button, the second window opens. (The first window needs to close or hide). Then I need to close my second window and need to stop the debugging. How to do it?
<Window x:Class="WpfApp5.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:WpfApp5"
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
xmlns:Control="clr-namespace:Syncfusion.Windows.Tools.Controls;assembly=Syncfusion.Tools.Wpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="Create" Height="50" Width="100" Click="btncreate"></Button>
</Grid>
MainWindow code-behind:
public partial class MainWindow : Window
{
public static TextBox textBox;
public MainWindow()
{
InitializeComponent();
}
private void btncreate(object sender, RoutedEventArgs e)
{
SecondWindow secondWindow = new SecondWindow();
secondWindow.Owner = this;
this.Hide();
secondWindow.ShowDialog();
}
}
Second window:
<Window x:Class="WpfApp5.SecondWindow"
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:WpfApp5"
mc:Ignorable="d"
Title="SecondWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<TextBlock Text="New Project Loaded" HorizontalAlignment="Center" Margin="50"></TextBlock>
</StackPanel>
</Grid>
Your problem seems to be that you're running code which is showing a window, maybe modally.
At the same time, you're trying to shut the app down.
You've not shown this code but if your btnCreate handler has shutdown in it just before
secondWindow.ShowDialog();
You'd be trying to shut the app down effectively at the same time as showing that window as a dialog.
What you want is your code to shut the app down but not whilst the UI is busy doing something else like show a window.
You could do that by moving your shutdown so it's in say the contentrendered event handler of that window you're showing.
Another option is to schedule the shutdown using dispatcher.
Application.Current.Dispatcher.InvokeAsync(new Action(() =>
{
Application.Current.Shutdown();
}), DispatcherPriority.ContextIdle);
If you still have errors you could consider instead using.
Environment.Exit(0);
This is a rather brute force approach compared to shutdown but if you're only doing this whilst debugging that probably won't matter.
In any case, you should ensure you don't have code which shows another window or something from the window.closing events of any of your windows. Since closing the app will necessarily involve closing windows.
Related
I am listening to the PreviewMouseUp event of a ToggleButton control. Depending on a condition the click event should be raised normally or aborted completely. So the IsChecked property is only set if the condition is true. For this I use the MouseButtonEventArgs.Handled property that is set to false if the condition is false.
If the ToggleButton is clicked and the condition is false the IsChecked property is not set as expected. But the application freezes for no reason. No further button clicks are possible.
If you click into the taskbar (context lost) the application is working again.
MainWindow.xaml
<Window x:Class="ButtonEventTest.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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ToggleButton Content="Test Button"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Padding="10"
PreviewMouseUp="UIElement_OnPreviewMouseUp"/>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void UIElement_OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (!IsMouseClickAllowed())
{
e.Handled = true;
}
}
}
Is there something that I am missing? Or is this a known WPF bug?
I am trying to bring up a window as a loading screen using the system.windows.window.show() method. The program is supposed continue running code and then close the window after it is done. The problem is that the window will not show the textblock I am trying to display. But when I do ShowDialog() it will
LoadingWindow lw = new LoadingWindow();
lw.Show();
//
//do stuff
//
lw.Close();
<Window x:Class="RevitAPITest3.LoadingWindow"
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:RevitAPITest3"
mc:Ignorable="d"
Title="Loading..." Height="450" Width="800" >
<Grid>
<TextBlock x:Name="text" FontSize="20" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Height="43" Width="291">testing</TextBlock>
</Grid>
</Window>
There's a fundamental difference between lw.Show() and lw.ShowDialog().
lw.Show() will immediately return to the next line of code without waiting for the window to close.
lw.ShowDialog() will wait for the window to close manually by the user, then return a value of true/false.
In your example code, your problem is that because lw.Show() returns immediately, it will then "do stuff" and then call lw.Close() which closes your window before you even see the window.
What you'll want to do is something like this. Notice: You never have to explicitly call lw.Close() because the window will automatically be closed as soon as it completes the lw.ShowDialog() line.
var result = lw.ShowDialog();
if (result.HasValue)
{
//
//do Stuff
//
}
Here is a complete working solution. Check to see where you are doing things differently and see if you can match this implementation.
MainWindow.xaml
<Window x:Class="LoadingWindowTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="768" Width="1024" WindowStartupLocation="CenterScreen">
<Grid>
<TextBlock Text="Main Window" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="32"/>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Threading.Tasks;
using System.Windows;
namespace LoadingWindowTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private LoadingWindow lw;
public MainWindow()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private async void OnLoaded(object sender, RoutedEventArgs e)
{
// Make the main window hidden until loading is done
this.Visibility = Visibility.Hidden;
// Show the Loading window
lw = new LoadingWindow();
lw.Show();
// Simulate a long running task
await Task.Delay(5000);
// Close the Loading window
lw.Close();
// Show the Main Window
this.Visibility = Visibility.Visible;
}
}
}
LoadingWindow.xaml (no xaml.cs shared because I didn't touch it)
<Window x:Class="LoadingWindowTest.LoadingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="LoadingWindow" Height="450" Width="800" WindowStartupLocation="CenterScreen">
<Grid>
<Grid>
<TextBlock x:Name="text" FontSize="20" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Height="43" Width="291">testing</TextBlock>
</Grid>
</Grid>
</Window>
Build and Run, then this is the Expected Output:
You should see the LoadingWindow on the center of the screen, then after 5 seconds, it closes and the MainWindow shows.
I have custom window with WindowState=WindowState.Maximized with border and thumb inside in the border, it seems that when the WindowState=WindowState.Maximized I cannot drag and move the custom window to different screen.
Xaml:
<Window x:Class="WpfApplication3.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"
WindowStyle="None">
<Border Name="headerBorder"
Width="Auto"
Height="50"
VerticalAlignment="Top"
CornerRadius="5,5,0,0"
DockPanel.Dock="Top"
Background="Red"
BorderThickness="1,1,1,1"
BorderBrush="Yellow">
<Grid x:Name="PART_Title">
<Thumb x:Name="headerThumb"
Opacity="0"
Background="{x:Null}"
Foreground="{x:Null}"
DragDelta="headerThumb_DragDelta"/>
</Grid>
</Border>
</Window>
C#:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
WindowState = System.Windows.WindowState.Maximized;
}
private void headerThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
Left = Left + e.HorizontalChange;
Top = Top + e.VerticalChange;
}
}
I've also overridden MouseLeftButtonDown method and using DragMove() inside but without success. I've also tried to subscribe to thumb's MouseLeftButtonDown and write there DragMove() but without success.
By default, maximized windows cannot be moved, thus Left and Top have no effect. One option would be to register to the Thumb.DragStarted event and check if the window is maximized. If yes, you can set WindowState.Normal and successively update the Left and Top properties.
In code, this would look somewhat like this:
private void Thumb_OnDragStarted(object sender, DragStartedEventArgs e)
{
// If the window is not maximized, do nothing
if (WindowState != WindowState.Maximized)
return;
// Set window state to normal
WindowState = WindowState.Normal;
// Here you have to determine the initial Left and Top values
// for the window that has WindowState normal
// I would use something like the native 'GetCursorPos' (in user32.dll)
// function to get the absolute mouse point on all screens
var point = new Win32Point();
GetCursorPos(ref point);
Left = point - certainXValue;
Top = point - certainYValue;
}
You can learn more about GetCursorPos here.
However, I would strongly advise you to use the WindowChrome class that comes with .NET 4.5 and that was also suggested by Max in the comments. You just have to use the following code and you have the functionality you're asking for:
<Window x:Class="ThumbMaximizedWindow.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"
WindowStyle="None"
WindowState="Maximized">
<WindowChrome.WindowChrome>
<WindowChrome />
</WindowChrome.WindowChrome>
</Window>
I have a Mainwindow and a groupbox inside it.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication1.MainWindow"
Title="MainWindow"
Height="600" Width="800">
<Grid x:Name="MainGrid">
<GroupBox Header="Diagram Design" Name="gbDiagDesign">
</GroupBox>
</Grid>
</Window>
A simple UserControl
<UserControl x:Class="WpfApplication1.Controls.EntityControl"
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"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="100">
<Grid>
<Button x:Name="btn_show" Content="show me" />
</Grid>
</UserControl>
and another window with an OK button in it,
the question is how do I add the UserControl to the Groupbox in the MainWindow after I press the OK button.
public partial class NewEntity
{
public NewEntity()
{
InitializeComponent();
}
private void OK_Click(object sender, RoutedEventArgs e)
{
EntityControl entcon = new EntityControl();
**MainWindow.gbDiagDesign.Children.Add(**
}
the last row gives me an error, "an object reference is required for the nonstatic field.."
You can access MainWindow using Application.Current.MainWindow but it will return instance of Window class. Typecasting is required to convert it to actual class instance i.e. MainWindow.
This should work:
((MainWindow)Application.Current.MainWindow).gbDiagDesign.Add(entcon);
WPF is meant to be programmed using the MVVM pattern. If you do it another way, you will have to fight WPF all along instead of using it's great power. If you insist on doing it the other way, at least make the compiler happy:
MainWindow is a instance variable of your application class. You are not inside your application class, so you need an instance of your application class first to access MainWindow. You will also need to cast it to your Window type.
I have a window with a Grid on.
On this I have some buttons, one of which when clicked will create a new 'PostIt' which is a user control I have created.
What I want to do is click on a 'PostIt' and have that control on top of all the others.
I have tried...
Grid.SetZIndex(sender, value);
Which seems to be the correct code, no errors, just not movement of the control :(
The problem may lie in the fact that the code for the click is in the user control and not the mainwindow cs file. Does this matter?
The 'PostIt' is simply a border with a text box in it.
Are you calling Grid.SetZIndex(sender, value) in a handler of the PostIt mouse click, or a handler for a control inside the PostIt? What is the value that you are setting?
Here is an example that works:
<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:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" MouseUp="UserControl_MouseUp">
<Grid>
</Grid>
</UserControl>
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void UserControl_MouseUp(object sender, MouseButtonEventArgs e)
{
Panel.SetZIndex(this, Panel.GetZIndex(this) + 2);
}
}
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 Background="Green" Margin="40,40,100,100" Panel.ZIndex="0" />
<local:UserControl1 Background="Red" Margin="140,140,10,10" Panel.ZIndex="1" />
</Grid>
</Window>
Jogy
This may not be the best solution, but it's the one that worked for me; I was re-ordering two grids:
GridOnBottom.SetValue(Grid.ZIndexProperty, (int)GridOnTop.GetValue(Grid.ZIndexProperty) + 1);
...with GridOnBottom and GridOnTop renamed to the instances of the objects you're re-ordering. Granted, it's not the best solution, but it works.