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;
Related
I have three XAML files, they are mainwindow.xaml,login.xaml,homepage.xaml. Since the files can be navigated through frames, i added a frame to main window which fits the whole screen.
XAML of MainWindow:
<Window x:Class="Myproject.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" WindowState="Maximized" Initialized="Window_Initialized">
<Grid>
<Frame Name="pageFrame"></Frame>
</Grid>
</Window>
CS file of MainWindow:
private void Window_Initialized(object sender, EventArgs e)
{
pageFrame.Height = SystemParameters.WorkArea.Height-10;
pageFrame.Width = SystemParameters.WorkArea.Width;
pageFrame.Navigate(new login());
}
It navigates perfectly to login page and perform login actions there.
The problem is it does not navigate to the homepage.xaml from the login.xaml.cs
Code used for navigating to homepage.xaml from login.xaml.cs
MainWindow mw = new MainWindow();
mw.pageFrame.Navigate(new homepage());
This code goes in a if statement section and i checked by using breakpoints if these statements are executed. And it does execute those and the objects are populated but the naviagtion does not occur.
What am i doing wrong? Is this not the correct approach?
The problem is, well, mw is a new window and it is not even shown at all. And you are staying in your old instance of MainWindow, nothing happens to your old MainWindow.
You need to navigate from within your old MainWindow, not a new one.
((MainWindow)(Application.Current.MainWindow)).pageFrame.Navigate(new homepage());
You have a reference to your main window, Application.Current.MainWindow, but you need to cast it into your own type of MainWindow first.
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.
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
}
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.
There is currently not an available WPF viewer for Active Reports 6. I was attempting to use a host control to display the viewer in a interop host but I'm not having much luck. Has anyone else attempted this successfully? I can't even get the wrapper Viewer control to add to the project toolbox as a custom control at this point. I'm hoping to avoid recreating the wheel.
The existing ActiveReports Viewer works fine in WPF. You can use the below XAML to host it in WPF:
<Window x:Class="ARViewerHostedInWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:arv="clr-namespace:DataDynamics.ActiveReports.Viewer;assembly=ActiveReports.Viewer6"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid>
<WindowsFormsHost Name="windowsFormsHost1">
<arv:Viewer x:Name="ARViewer" Dock="Fill" />
</WindowsFormsHost>
</Grid>
</Window>
The following code in the code-behind of the XAML file will connect a report to the viewer in the XAML above and run it:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
NewActiveReport1 rpt = new NewActiveReport1();
this.ARViewer.Document = rpt.Document;
rpt.Run();
}
}
I'm using the currently available version of ActiveReports 6 to test this.
Hope this helps!
Scott Willeke
GrapeCity