ShowDialog makes app window disappear from windows' Alt-Tab list? - wpf

i am new to WPF, and i am trying to open a modal dialog from inside my main window:
public partial class MainWindow : Window
{
protected void OpenCommandExecuted(object target, ExecutedRoutedEventArgs e)
{
DataSearchWindow w = new DataSearchWindow();
w.Owner = this;
w.ShowDialog();
}
...
}
and XAML for my DataSearchWindow looks like this:
<Window x:Class="DataSearchWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ShowInTaskbar='False'
WindowStartupLocation='CenterOwner'
WindowStyle='ToolWindow'
...>
...
</Window>
Everything works until I press Alt-Tab to switch to another application. When I do that my application disappears from the list shown when Alt-Tab is pressed. It is still in the taskbar and I can return to it using mouse, bu not with Alt-Tab. Has anyone seen this?
konstantin

This is because of the modal dialog - you cannot Alt-Tab back to the application until the dialog is closed. Since the WindowStyle is set as ToolWindow, it won't show up in Alt-Tab. However, if it were a regular window, the dialog window would show up in Alt-Tab.
Note that this isn't a WPF issue - it is consistent with, for example, a Windows Forms application.

Related

WPF WebBrowser inside a Popup

I want to have Popup with WebBrowser in it that appears when I click on window created with WinForms. I created user control that contains DockPanel with WebBrowser. I put this control in Popup and then when I click on window whole Popup appears except for WebBrowser. To check my control I put it directly to window - and it works. Is this problem because of mixing WPF and WinForms or WebBrowser just will not work in Popup?
MyControl
<DockPanel>
<WebBrowser Navigate="..." />
</DockPanel>
Popup
Popup foo = new Popup()
{
Child = MyControl
}
Event
void OnClick(object sender, EventArgs e)
{
foo.IsOpen = true;
}

manipulate selected text on wpf webbrowser

I'm creating a epub books reader.
After displaying the book i want to allow users to add some annotation to the book.
To display the book, I'm using a wpf webbrowser control that loads local html files
I want to manipulate selected text on this control by creating a context menu or showing a popup
i've tried to change the control's contextmenu but by searching i found that isn't possible
this is an example of what i want to do with selected text:
IHTMLDocument2 htmlDocument = (IHTMLDocument2)webBrowser1.Document;
IHTMLSelectionObject currentSelection = htmlDocument.selection;
if (currentSelection != null)
{
IHTMLTxtRange range = currentSelection.createRange() as IHTMLTxtRange;
if (range != null)
{
MessageBox.Show(range.text);
}
}
WPF's native browser control will not let you set a custom context menu.
It gets even worse ; while your mouse is over the browser component, or if it has focus, it will not catch events generated by your input either.
A way around this, is to use the windows forms browser control inside a WindowsFormsHost.
To start, add Windows.Forms to your project references.
Then, do something like the following:
XAML:
<Window x:Class="blarb.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>
<WindowsFormsHost Name="windowsFormsHost" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</Grid>
</Window>
C# code:
public partial class MainWindow : Window
{
private System.Windows.Forms.WebBrowser Browser;
public MainWindow()
{
InitializeComponent();
//initialise the windows.forms browser component
Browser = new System.Windows.Forms.WebBrowser
{
//disable the default context menu
IsWebBrowserContextMenuEnabled = false
};
//make a custom context menu with items
System.Windows.Forms.ContextMenu BrowserContextMenu = new System.Windows.Forms.ContextMenu();
System.Windows.Forms.MenuItem MenuItem = new System.Windows.Forms.MenuItem {Text = "Take Action"};
MenuItem.Click += MenuItemOnClick;
BrowserContextMenu.MenuItems.Add(MenuItem);
Browser.ContextMenu = BrowserContextMenu;
//put the browser control in the windows forms host
windowsFormsHost.Child = Browser;
//navigate the browser like this:
Browser.Navigate("http://www.google.com");
}
private void MenuItemOnClick(object sender, EventArgs eventArgs)
{
//will be called when you click the context menu item
}
}
This does not yet explain how to do your highlighting though.
You could listen for the event fired by the browser component when it is done loading, and then replace portions of the document it loaded, injecting html code to do the highlighting.
Keep in mind that that might be tricky in some situations (when selecting text across divs, spans or paragraphs for example)
using mshtml;
private mshtml.HTMLDocumentEvents2_Event documentEvents;
in constructor or xaml set your LoadComplete event:
webBrowser.LoadCompleted += webBrowser_LoadCompleted;
then in that method create your new webbrowser document object and view the available properties and create new events as follows:
private void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
{
documentEvents = (HTMLDocumentEvents2_Event)webBrowserChat.Document; // this will access the events properties as needed
documentEvents.oncontextmenu += webBrowserChat_ContextMenuOpening;
}
private bool webBrowserChat_ContextMenuOpening(IHTMLEventObj pEvtObj)
{
return false; // ContextMenu wont open
// return true; ContextMenu will open
// Here you can create your custom contextmenu or whatever you want
}

The best approach to show/hide windows indpendently

I am a student and am building a C# WPF application. It has three windows:
Sign in window
Create account window
and Main application window.
I uploaded a figure to show the type of navigation I am trying to implement:
I do not think it is correct to make a window show up/hide inside the close/load event of another window.
Can someone show me the right way to implement this navigation?
Also, is it a good practice to make the three windows private properties of the application class?
The last window has a frame control to support page navigation. Again, is it better to make the three pages private properties of MainWindow application?
I am sorry if this is so obvious or easy to do.
Thanks
I would not have the three windows as properties of the application. I'd instanciate a copy of the sign-in window and use that as my central point of control.
When the user logs in, hide the sign in window, show a new main window and add a hook on the main windows Closed event.
e.g
if (logonSuccess)
{
var mainWindow = new MainWindow();
mainWindow.Closed += ReshowSignupWindow;
}
I'd also have the sign-in window do the same for the create account window. Thus, I'd have the create account window return to the signup window which would either reshow itself or start the main window if an account was created.
e.g.:
// In sign-in window, handle the create window being closed
private void CreateWindowClosedHandler(object sender, EventArgs e)
{
if (accountCreatedOK)
{
ShowMainWindow();
}
else
{
ReshowSignupWindow();
}
}
I'd probably look at having the create account window shown as a dialog window via a call to ShowDialog().
Hope that helps...
Something like this code might do it (untested, I just typed it in visual studio to autoformat the code)
The XAML is for the Login Dialog. The RegistrationDialog should be similar, except for the button and handler for the registration Button.
<Window x:Class="WpfApplication1.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="LoginWindow">
<StackPanel>
<Button IsDefault="True" Content="Submit" Click="SubmitButton_Click"/>
<Button IsCancel="True" Content="Cancel" />
<Button Content="CreateAccount" Click="CreateAccountButton_Click"/>
</StackPanel>
</Window>
//Handler of LoginWindow and RegistrationWindow
private void SubmitButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
//Handler of LoginWindow only
private void CreateAccountButton_Click(object sender, RoutedEventArgs e)
{
this.IsCreatingAccount = true;
this.DialogResult = false;
}
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
bool isCanceled;
while (loginWin.ShowDialog() == false && !isCanceled)
{
if (loginWin.IsAccountCreationRequested)
{
if (registrationWin.ShowDialog())
{
isCanceled = true;
}
else
{
loginWin.IsAccountCreationRequested = false;
}
}
else
{
isCanceled = true;
}
}
if (loginWin.DialogResult) MainWindow.Show();
}
}
I am currently working on a Silverlight Application which is more or less similar to your application. What i feel is your can have 2 xaml controls(one for Login and other for your main application). For create account, you can use a child window which will be called from login control. And use a TabControl in your main application which will hold your other 3 xaml controls(Page1.xaml, Page2.xaml and Page3.xaml). Feel free to ask if you have any issues.
Dont forget to mark my reply as answer if it solves your problem.
I suggest you to follow the pattern. Your logic looks tightly binding with UI(user Interface) and logics.
The best pattern i like is for WPF or Silverlight is MVVM(Model View View Model). There are lot of Examples available in google for MVVM.
Just put a glance in anyone MVVM example you will be clear in developing WPF or Silverlight app.
some links are below,
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
http://www.c-sharpcorner.com/UploadFile/raj1979/simple-mvvm-pattern-in-wpf/
http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute

Unexpected behaviour of System.Windows.Window.ShowDialog() when no other windows are open. Any idea why?

I picked up on this (with some effort) when my WPF MVVM application tried to show two consecutive error dialog windows before the main window was launched: After OKing the first window, the application went into a loop and the second error dialog never showed up.
I fixed the problem, but I was hoping someone could enlighten me as to why this happened.
It seems that, if there are no non-modal open windows, if one dialog window has been closed, all new dialog windows are immediately closed, without displaying.
Its very easy to reproduce, so here is some highly conceited code to illustrate the problem. This code is complete, so using just this, you should be able to reproduce it.
Create a Window control for the dialog window, with no code behind, and just the following XAML:
<Window x:Class="ForumExampleShowDialogIssue.OKDialogWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OKDialogWindow" Height="300" Width="300">
<StackPanel>
<TextBlock Text="This is a Window with a single button. The button is set to Cancel, so it closes the window."
TextWrapping="Wrap"
Margin="5"/>
<Button Content="OK" IsCancel="True" IsDefault="True"
Margin="5"/>
</StackPanel>
Next, use the standard WPF App class, with nothing new in the XAML, but with the following in the code behind:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
OKDialogWindow alwaysOpen = new OKDialogWindow();
alwaysOpen.Show();
while (true)
{
OKDialogWindow dialogWindow = new OKDialogWindow();
Console.WriteLine("Before show");
dialogWindow.ShowDialog();
Console.WriteLine("After show");
}
}
Delete the MainWindow.XAML if it exists, and remove the reference to it from the App.XAML header.
Run. (the program, not like Forest).
This works as expected. The alwaysOpen window remains open, while one after the other dialogWindow instances appear in dialog mode, closing when OK is clicked, then showing the next one.
HOWEVER, this breaks when you change OnStartup to the following:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
while (true)
{
OKDialogWindow dialogWindow = new OKDialogWindow();
Console.WriteLine("Before show");
dialogWindow.ShowDialog();
Console.WriteLine("After show");
}
}
When there is no constantly open window, the first dialog window is the only one that works. After that, countless "Before show" and "After show" messages are printed to the console, but no new dialog windows appear - they are closed automatically as soon as they are shown.
Surely this can't be the intended behaviour? Do you get the same result? Any idea why this happens?
This is the intended behavior.
by Default the first open window is the MainWindow.
By default the only window in the list becomes the MainWindow (if others are to be removed).
Application Class is designed to exit if no windows are present in
windows list.
Check this:
http://www.ageektrapped.com/blog/the-wpf-application-class-overview-and-gotcha/
Resolve
You can goto the App.xaml file and add this in the root <Application> node:
ShutdownMode="OnExplicitShutdown"
This means that even when you close all the windows, the application still runs until you explicitly call the InvokeShutdown() Method.
The default value of ShutdownMode is OnMainWindowClose。
Explanation
In your first snippet, you create a window first that never close. This is the MainWindow and it never close. Thus Application never shutdown. But in your second snippet, your MainWindow is the first dialog that you have created. Application will shutdown as soon as the window close. Your other dialogs would never show after Application shutted down, right?
See MSDN: https://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode(v=vs.110).aspx.

Open a window after the mainWindow and activate it

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();

Resources