I'm writing small notification component, however I have a problem with showing multiple notification at once.
My alert/notification window inherits from window class. The contstructor of Alert looks like that
public Alert()
{
InitializeComponent();
Focusable = true;
ShowActivated = false;
ShowInTaskbar = false;
//Topmost = true;
AllowsTransparency = true;
Opacity = 1;
// Set up the fade in and fade out animations
_Hint = "hint";
Loaded += new RoutedEventHandler(DesktopAlertBase_Loaded);
}
In main window of application I have a list of alerts, thanks to this I know where to place alerts on the screen. If I want to show an alert I create an instance of Alert class and then I use Show() method. Alerts are shown and everything is OK except the fact that I can use/move/interact with only last alert window (last created window).The rest of alert windows can't be clicked. However if I close last window I can use one before last and so on... Is it possible to make multiple windows clicable/active ?
Can you please, provide code, where you use show method? It looks like you are using ShowDialog() method instead of Show().
Another possibility is some locks in your DesktopAlertBase_Loaded() method.
Related
I'm writing a winform app that lives in the notification tray and the user can open/close it by interacting with the notifyIcon control.
Whene some events happens, I need to notify the user about but the notifyIcon's BalloonTip is not enough, because I need to display a collection of messages paired with buttons, that the user must click in order to acknowledge the app that he really saw it(very serious stuff)
How can I accomplish that? Does winforms provide a specific API? If there's not such API, how do I set up a completely blank form?
Thanks a lot.
Take a look at this question. The notifyIcon1_Click displays a context menu at the mouse position. In your case you need to display a form.
I think the screenshot you put shows a regular form without the title bar. So you just have to make a new form and show it at the mouse position when the user clicks the notification icon.
To remove the title bar from a form just do this form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; or form.ControlBox = false;
form.MaximizeBox = false;
form.MinimizeBox = false;
form.Text = "";
As #dburner said
form.ControlBox = false;
form.MaximizeBox = false;
form.MinimizeBox = false;
form.Text = "";
worked for me. However the first option doesn't give the aero feel.
I have two wpf windows in my wpf application.
1) When i click on the load button it loads the second Window. The secong window takes 15 to 20 secs to load.
How do i add a progress bar to show a loading window and when the second window loads close the progress bar.
I was recently working on a loading window for my app where you click the app and it takes about 10s to load. I have a loading window with an intermediate loading bar. The key was to put the loading window in a different thread to enable the animation to run while it was loading the other window on the main thread. The problem was to make sure we do stuff propertly (like when we close we close the window should stop the thread... etc).
In the code below... LoadingWindow is a small window with a progress bar on it, SecondWindow would be the window that is slow to load.
public void OnLoad()
{
Dispatcher threadDispacher = null;
Thread thread = new Thread((ThreadStart)delegate
{
threadDispacher = Dispatcher.CurrentDispatcher;
SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(threadDispacher));
loadingWindow = new LoadingWindow();
loadingWindow.Closed += (s, ev) => threadDispacher.BeginInvokeShutdown(DispatcherPriority.Background);
loadingWindow.Show();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
// Load your second window here on the normal thread
SecondWindow secondWindow = new SecondWindow();
// Presumably a slow loading task
secondWindow.Show();
if (threadDispacher != null)
{
threadDispacher.BeginInvoke(new Action(delegate
{
loadingWindow.Close();
}));
}
}
There are many ways you can accomplish that. An easy way would be to create a third window or panel with the progress bar or a waiting animation. That third window is in charge of loading your second window and get displayed as soon as you click the load button on the first window. When loading of the second window is completed, the third window with the progress bar closes and the second window gets displayed.
hope this helps.
You could use the BusyIndicator as part of the WPF extended toolkit. You can download it here: http://wpftoolkit.codeplex.com/wikipage?title=BusyIndicator
On immediate loading of the new window before you do your expensive processing that takes forever, you can set the IsBusy to true. When processing is done, set IsBusy back to false. This method involves wrapping your XAML in the BusyIndicator in the 2nd window, which may or may not be what you want.
In method that is working in the background, i have two important lines :
createPopup();
MessageBox.Show(sth);
more lines
more lines
createPopup() just creates a popup, adds a grid as a child and shows popup.
My question is, why first shows up messageBox, then shows up Popup, which appears after all lines in this method done ? How could I make this popup to show before all lines in this method will be done ?
All the UI changes are normally queued up and will be shown at once on the screen.
And this does not include MessageBox. So it shows up immediately and prevents the execution, until user clicks on Ok. Hence eventhough your popUP is first executed, it will be shown in the UI only after the MessageBox.
For your problem, Try placing your MessageBox.Show(something) in a separate thread.
createPopup();
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("some message");
});
more lines
more lines
Give it a try. I am not sure whether it solves your problem or not as I dnt know the code in createPopUp() method.
Creating the pop-up, does not actually draw it on the screen until the Layout event. If you want to ensure that the pop-up has been drawn before you display the pop-up, attach an event handler to the pop-up's LayoutUpdated event and display the message box from within that event handler. Be sure to detach the event handler as well or you will see multiple message boxes.
public InitPage()
{
Popup popup = new Popup();
popup.LayoutUpdated += popup_LayoutUpdated;
LayoutRoot.Controls.Add(popup);
}
void popup_LayoutUpdated(object sender, object e)
{
popup_LayoutUpdated -= popup_LayoutUpdated;
MessageBox.Show("hello");
}
The popup that gets opened in my app always stays on top. It goes away when i minimize the app. But otherwise if the app opens a new window or if i switch to another program without minimizing the app, the popup stays on top. How do i hide the popup when the app loses focus?
Thanks
It sounds like you need to set the owner/parent of the popup to the correct window by setting the Owner property to the window that created it.
You can pass owner (parent window) to the constructor of the popup window and then specify
public class PopupWindow: Window
{
public PopupWindow(Window owner)
{
this.Owner = owner;
}
}
Then open your popup window
Now to open your popup window you will use something like this:
var popup = new PopupWindow(ownerWindow);
popup.Show();
or if caller is a parent (owner)
var popup = new PopupWindow(this);
popup.Show();
In my Windows Form's Form_Load event, I want to show a FolderBrowserDialog to let the user select a directory, and if the directory they've selected is not valid (meaning it lacks certain files that the application needs), I want to show it again. However, when I create a new FolderBrowserDialog, it does not appear when I call ShowDialog.
while (ValidDirectorySelected() == false && tryAgain == true)
{
using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{
dialog.ShowNewFolderButton = false;
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
{
tryAgain = false;
}
}
}
When I step into it, the dialog.ShowDialog() line is reached on the second time, and then nothing happens. The dialog does not appear, and the debugger doesn't move on. It just stops. It works perfectly the first time, but not the second. I've even tried just copying that entire using block and pasting it right after the first one, and the same thing happens. The dialog shows only once.
What do I need to do to show a FolderBrowserDialog more than once?
Solution:
Passing 'this' to ShowDialog fixed my issue. I also moved the using to outside of the while loop, to avoid needlessly re-creating the dialog.
Minimize Visual Studio, you'll find the dialog back.
This is a focus issue, triggered because you display the dialog in the Load event. When the dialog closes, there is no window left in your app that can receive the focus. Your Load event hasn't finished running so the app's main window isn't yet visible. Windows has to find a window to give the focus to and will select one from another program. Like Visual Studio.
When you display the dialog again, it cannot steal the focus back because Visual Studio has acquired it. So the dialog appears behind Visual Studio's main window, out of view.
You'll have to fix this by allowing your main window to become visible. And call dialog.ShowDialog(this) to be completely sure. You could use the Shown event, for example.
Try this:
using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{
while (ValidDirectorySelected() == false && tryAgain == true)
{
dialog.ShowNewFolderButton = false;
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
{
tryAgain = false;
}
}
}
...move your using outside the while loop to keep from destroying the folder browser every time. You don't have to do that. You can reuse FolderBrowserDialog.