Open a window after the mainWindow and activate it - wpf

In my application is required the user to select an item from a list before continues uses the application.
To do this, I have a window with the desired items and I display it when the MainWindow displays.
public MainWindow()
{
InitializeComponent();
var itemsWindow = new ItemsWindow();
itemsWindow.Show();
}
The problem is that the window opens in background. How can I open the window in foreground?
The preferable would be to open the itemsWindow on applications start up and onClose event of itemsWindow to display the mainWindow, but I think this approach is far away from my knowledge. Nevertheless, I would appreciate it if someone could post something for how to achieve this.
Thanks

Use ShowDialog() method instead. That way, you won't have to worry about activating that window and user won't be able to interact with MainWindow until ItemsWindow has been closed.
Example:
var itemsWindow = new ItemsWindow();
itemsWindow.ShowDialog();

Related

How to disable a user control on main window from page WPF

I have a user control sitting on my main window, It is a menu.
When a user tries editing objects on a page I want to disable this user control while the user is on edit mode so they do not navigate off the page they are editing.
I am having trouble accessing the user control(placed on the main window) from a page
User Control Name - MenuView
The code below is on the page load of the page
MainWindow mainWindow = new MainWindow();
mainWindow.MenuView.IsEnabled = false;
This does not seem to work though
You need to get a reference to the existing instance of the MainWindow instead of creating a new one.
If you don't care about MVVM, the easiest way to do this would probably be to use the static Application.Current.Windows or App.Current.MainWindow property:
MainWindow mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
if (mainWindow != null)
mainWindow.MenuView.IsEnabled = false;
Note that this approach does create a coupling between your classes, but this is inevitable if you access a field of the window from in the Page class.
You probably want to look into the MVVM design pattern but that's another story.

getting values from a second window to the main window in wpf

I have a wpf application which will work minimized. The application will show a second window when system wakes up from sleep. In the second window there is a combobox and a button. when i click on the button it should set the value of a variable in the mainwindow with the value of combobox. But the problem is the variable in mainwindow is not accessible in second window. How to do this?? I searched a lot in net. But unable to find a working solution. Any suggestions??
You could use Event / delegate approach to get it:
A code snippet to sum-up:
In your First window when creating the second one do
Window1 win = new Window1();
win.GetEvent += win_GetEvent;
win.ShowDialog();
And in the second window you have:
public object ValueToGet;
public delegate object GetValueDelegate(object _value);
public event GetValueDelegate GetEvent;
public Window1()
{
InitializeComponent();
GetEvent.Invoke(ValueToGet);
}
Well I don't know which your specific requirment but just to intreduce the approach

To set the owner property for WPF window

I am Working on creating addin for Autodesk Inventor, I have class lib project in that I will show a wpf window on button click, that works great. However, I could not set the owner property for my window.. In my research I came to know that we need to get the parent window object..
If you're not able to get parent window, you can try setting the parent using window handle.
I'm not familiar with Autodesk Inventor and how you create plugin for the application so I don't know if you can get window handle but I guess you could know process id or window caption/title or some other information that can help you get the parent window handle (you should Google how to get window handle). Once you have handle of parent window you can set it as an owner of your window using WindowInteropHelper.
Here's just a sample how to use WindowInteropHelper:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
IntPtr parentWindowHandler = IntPtr.Zero;
// I'll just look for notepad window so I can demonstrate (remember to run notepad before running this sample code :))
foreach (Process pList in Process.GetProcesses())
{
if (pList.MainWindowTitle.Contains("Notepad"))
{
parentWindowHandler = pList.MainWindowHandle;
break;
}
}
var interop = new WindowInteropHelper(this);
interop.EnsureHandle();
// this is it
interop.Owner = parentWindowHandler;
// i'll use this to check if owner is set
// if it's set MainWindow will be shown at the center of notepad window
WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
}
}
I'm just reiterating the example that user1018735 gave. I develop Inventor Add-ins so I modified the code above to make sure I am always working with the correct Inventor session since multiple instances of Inventor can be open at once. I do this by passing my already known application object to my form through the _App parameter; then since the process MainWindowTitle is always the same as the applications caption I match the two.
I'm running this in a WPF Class Library # VB.Net 4.5.1.
Here is a peek at my code that works in Inventor 2014...
Public Sub New(ByVal _App As Inventor.Application)
'This call is required by the designer.
InitializeComponent()
'Find the Inventor Window Handle.
Dim InvWndHnd As IntPtr = IntPtr.Zero
'Search the process list for the matching Inventor application.
For Each pList As Process In Process.GetProcesses()
If pList.MainWindowTitle.Contains(_App.Caption) Then
InvWndHnd = pList.MainWindowHandle
Exit For
End If
Next
Dim InvWndIrp = New WindowInteropHelper(Me)
InvWndIrp.EnsureHandle()
InvWndIrp.Owner = InvWndHnd
...
// Create a window and make this window its owner
Window ownedWindow = new Window();
ownedWindow.Owner = this;
ownedWindow.Show();

ShowDialog() behind the parent window

I am using ShowDialog() with WindowStyle = WindowStyle.SingleBorderWindow; to open a modal window in my WPF (MVVM) application, but it lets me navigate to parent window using the Windows taskbar (Windows 7).
I've found an answer here: WPF and ShowDialog() but it isn't suitable for me because I don't need an "always on top" tool window.
Thanks in advance
Try setting the Owner property of the dialog. That should work.
Window dialog = new Window();
dialog.Owner = mainWindow;
dialog.ShowDialog();
Edit:
I had a similar problem using this with MVVM. You can solve this by using delegates.
public class MainWindowViewModel
{
public delegate void ShowDialogDelegate(string message);
public ShowDialogDelegate ShowDialogCallback;
public void Action()
{
// here you want to show the dialog
ShowDialogDelegate callback = ShowDialogCallback;
if(callback != null)
{
callback("Message");
}
}
}
public class MainWindow
{
public MainWindow()
{
// initialize the ViewModel
MainWindowViewModel viewModel = new MainWindowViewModel();
viewModel.ShowDialogCallback += ShowDialog;
DataContext = viewModel;
}
private void ShowDialog(string message)
{
// show the dialog
}
}
I had this problem but as the Window was being opened from a view model I didn't have a reference to the current window. To get round it I used this code:
var myWindow = new MyWindowType();
myWindow.Owner = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
You can use: myWindow.Owner = Application.Current.MainWindow;
However, this method causes problems if you have three windows open like this:
MainWindow
|
-----> ChildWindow1
|
-----> ChildWindow2
Then setting ChildWindow2.Owner = Application.Current.MainWindow will set the owner of the window to be its grandparent window, not parent window.
When the parent window makes (and shows) the child window, that is where you need to set the owner.
public partial class MainWindow : Window
{
private void openChild()
{
ChildWindow child = new ChildWindow ();
child.Owner = this; // "this" is the parent
child.ShowDialog();
}
}
Aditionally, if you don't want an extra taskbar for all the children... then
<Window x:Class="ChildWindow"
ShowInTaskbar="False" >
</Window>
Much of the reason for the MVVM pattern is so that your interaction logic can be unit tested. For this reason, you should never directly open a window from the ViewModel, or you'll have dialogs popping up in the middle of your unit tests.
Instead, you should raise an event that the View will handle and open a dialog for you. For example, see this article on Interaction Requests: https://msdn.microsoft.com/en-us/library/gg405494(v=pandp.40).aspx#sec12
The problem seems to be related to Window.Owner, and indeed if you judge by previous knowledge that you might have of the Win32 API and WinForms, a missing owner would be the typical cause of such a problem, but as many have pointed out, in the case of WPF that's not it. Microsoft keeps changing things to keep things interesting.
In WPF you can have a dialog with a specific owner and you can still have the dialog appear in the taskbar. Because why not. And that's the default behavior. Because why not. Their rationale is that modal dialogs are not kosher anymore, so you should not be using them; you should be using modeless dialogs, which make sense to show as separate taskbar icons, and in any case the user can then decide whether they want to see different app windows as separate icons, or whether they want to see them grouped.
So, they are trying to enforce this policy with complete disregard to anyone who might want to go against their guidelines and create a modal dialog. So, they force you to explicitly state that you do not want a taskbar icon to appear for your dialog.
To fix this problem, do the following in the constructor of your view class:
ShowInTaskbar = false;
(This may happen right after InitializeComponent();
This is equivalent to Xcalibur37's answer, though the way I figure things, since WPF forces you to have both a .cs file and a .xaml file, you might as well put things that are unlikely to change in the .cs file.
Add "ShowInTaskbar" and set it to false.
Even if this post is a bit old, I hope it is OK that I post my solution.
All the above results are known to me and did not exactly yield the desired result.
I am doing it for the other googlers :)
Lets say f2 is your window that you want to display on top of f1 :
f2.Owner = Window.GetWindow(this);
f2.ShowDialog();
That's it , I promise it will not disappear !
HTH
Guy

WPF custom control question

i've done this before but i cannot find my old code.
how do you embed a window inside a window.
let say i created a custom form and saved it as Window1.xaml, and want to embed it in Window2.xaml, without copy and pasting the xaml code.. TIA
EDIT: i think my question is somewhat misleading, i'll rephrase it.
i have this Window1.xaml i added custom headers and background images/colors.
then in Window2.xaml, i want Window1 to be a custom control and embed it here.
not sure if its Content Presenters, still googling for the answer :)
You can't host a WPF Window inside another WPF Window, but you could move the content from one Window to another:
var window1 = new Window1();
var window2 = new Window2();
var content = window1.Content;
window1.Content = null;
window2.Content = content;
Note that you set window1.Content to null or else you get an exception, since the content will have a visual parent otherwise.
UPDATE
It appears all you need to do is to copy all the XAML between the <Window></Window> tags in Window1 into a new UserControl, then host that user control in Window2.
I believe you should make use of Pages or usercontrols in such cases. This way you can navigate to other parts/pages/controls defined in application. CodeKaizen is right , you can't host a window inside another window
I'm not sure you can do that - however, you shouldn't put the user interface directly into a window, use a normal control (either custom or user) instead and reuse that in your windows.
I know you can do it in code behind
//Window you want to show
Window1 child = new Window1();
object content = child.Content;
child.Content = null;
//Where to show
this.grid1.Children.Clear();
this.grid1.Children.Add((UIElement)content);
Hope helps!
It sounds like you really want a UserControl. Change Window1's type from Window to UserControl and then put that UserControl in Window2.

Resources