I use StatusStrip that contains ToolStripStatusLabel. OS - Windows 7, framework 2.0.
Usually all displayed normal, but sometimes ToolStripStatusLabel looks like black box:
I read that windows bug, but how I can fix it?
This is an obscure bug, triggered when you display the form with the Windows toolbar overlapping your StatusStrip. Moving the window away from the toolbar doesn't get the ToolStripItems on the status strip repainted properly. You'll find a bit of background in this forum post. There was a weak promise for a future fix for it, no idea if that ever happened. Probably not if you are running this on Win7.
You'll need to pay more attention to the position of the window, making sure that parts of it don't disappear underneath the toolbar. In general something you'd always consider, extra important as long as this bug doesn't get fixed. If you don't want to nail down the startup position (you ought to, users tend to like a window getting redisplayed where they last moved it) then simply change the form's StartPosition property to "CenterScreen".
This bug has never been fixed. It was in framework 2 and is still in framework 4.
The answer from Hans is a copy of the answer in social.msdn.microsoft.com.
But it is not helpful for me because "CenterScreen" does not solve the problem.
The cause of the problem is not the Windows Taskbar. The cause is a bug that does not draw the StatusStrip when the main Form is behind ANY other window at the first moment of drawing the StatusStrip. But this will also happen when you start the new process with Process.Start() from another process and the new process opens behind the window of another process.
I found a much better solution than the one proposed by Microsoft.
First I tried with
statusStrip.Invalidate();
but it does not work. So we need a stronger way to force Windows to redraw the StatusStrip. Important: The redrawing must happen when the Form with the StatusStrip is ALREADY in foreground! This is so easy that I don't understand why Microsoft does not suggest this method.
Timer mi_StatusTimer = new Timer();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
mi_StatusTimer.Interval = 500;
mi_StatusTimer.Tick += new EventHandler(OnTimerBugFix);
}
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
mi_StatusTimer.Start();
}
void OnTimerBugFix(object sender, EventArgs e)
{
mi_StatusTimer.Stop();
statusStrip.Hide();
Application.DoEvents();
statusStrip.Show();
}
Related
I want to make an application which has another screen in the extended screen in another monitor (or in my case projector), similar to the presenter view in power point.
I want to use C#, and I guess in windows form application or wpf template there is no dual screen application support.
My first guess is to make 2 separate project and connect them, but I'm not sure about it either.
Any idea how to do it, or at least someone has a tutorial related to it?
I've looked at google, but still not sure what the right question to the issue, since google always showed "how to set up dual screen" for users.
Please clarify anything if my question is unclear. Thanks.
The easiest method I can think of is to simply create a second form (assuming you use Window Forms for your project), so you'd have Form1 as the default, and Form2 as your second form.
Run Form1 by default, and then while loading Form1, do something like this:
if(System.Windows.Forms.Screen.AllScreens.Length > 1)
{
Form2 form2 = new Form2();
form2.Show();
}
Then within form2's shown event, set it's position to the second screen (and perhaps maximize it, depending on what you need).
private void Form2_Shown(object sender, EventArgs e)
{
this.Location = Screen.AllScreens[1].Bounds.Location;
this.WindowState = FormWindowState.Maximized;
}
From that point on (and provided you keep a reference to Form2 within Form1), you can easily exchange information between the two forms as needed. You could even expand it to support 3-4 monitors, simply by making multiple Form2's, one for each screen
I'm using the following to create 'toaster' style pop-ups:
Create popup "toaster" notifications in Windows with .NET
Unfortunately, after the message "disappears", there is still a 'task' in the taskbar. After showing multiple popups, there is a separate 'task' for each popup that was opened, all stacked on top of each other.
How can I close these after the opacity animation has completed?
I wrote my own toast implementation, perhaps you can find use of it! It's very simple, all you do is:
ToastMessage.Show("My message", "My Title");
And you're done! :) I'll keep updating it until I think it's perfect, but modify it as you wish! I'm yet to add things like animations and sound effects.
Here is the link:
GitHub WPFToastMessage
I figured this out and it's pretty easy!
I changed this (minus space at beginning):
< Storyboard>
To this:
< Storyboard Completed="Storyboard_Completed">
Then in the 'properties' pane under events, I double-clicked the new event that was auto-added and got this:
private void Storyboard_Completed(object sender, EventArgs e)
{
}
And simply added:
this.Close();
So I have my WinForms application with a StatusStrip. Inside this StatusTrip, there's a StatusLabel (it's not the default Label, as it's not supported for some reason).
Now, when I set StatusLabel.IsLink = true;, you'll get a hand cursor (which is great!). But now, if you do StatusLabel.Visible = false; the whole StatusStrip has a hand cursor on it right now. Making the StatusLabel visible again does not fix it.
This seems like either a .NET or C# bug to me.
My question is: is there any workaround for this, I'm not aware of? Either by fixing this hand cursor bug or by placing a real Label inside the StatusStrip? I've found out that when placing a MessageBox just right before you make the label non-visible, it's not doing this weird bug.
You can download a test solution here. In the Main.cs file there's a line with the MessageBox which you can uncomment. Try it yourself.
You can try setting the Cursor of your StatusStrip back to Default
private void toolStripStatusLabel1_Click(object sender, EventArgs e)
{
// UNCOMMENT THE LINE BELOW TO "FIX" IT
//MessageBox.Show("It's not doing the bug when showing this message.");
toolStripStatusLabel1.Visible = false;
statusStrip1.Cursor = Cursors.Default;
}
In the current released version of WP7 you have no programmatic control over the page stack.
I start at A, go to B, and then C. B is the data entry page for new items, so coming back from C I want to logically land at A. Currently I listen for navigation on B that comes from C and force another back onto A. However, the event doesn't happen soon enough to stop the page from displaying on-screen.
A -> B -> C
C -> A
A is the top level list page. B is the new item page. C is the item detail page.
This only occurs on one form so far so my workaround is to override OnNavigatedTo in the page I want to skip, and call "go back" programmatically. However, this has the undesired effect of briefly showing the page and then immediately navigating off of it.
Is there a workable way to stop the flicker?
Should my workaround instead be to take full control of page navigation, including go backs? This will leave the page stack is a strange state, but that would be hidden from the user if I control all navigation.
I know there is a new feature in Mango to pop a page from the page stack programmatically, but I'm curious to know if there is a solution to the problem in the released version.
Another motivation for this is I don't know what version will be best to target, the latest, or the one that is just enough for the app. For the time being I'm sticking with the live version.
You should read this blog post on solving circular navigation issues and you can download this recipe code which demonstrates non-linear navigation.
I have stopped the flickering by making the root frame transparent for the duration of the skip. This example isn't straight from my code.
Firstly on the page you wish to skip, override OnNavigatedTo and test to see where you have come from (this is where my code gets specific, I keep track of where I am):
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// If I've come from page C, go back again.
NavigationService.GoBack();
}
Secondly, in the main App.xaml.cs register an event handler for Navigating (I put it in public App() constructor):
RootFrame.Navigating += RootFrame_Navigating;
Finally, flesh them out to hide the frame and show it again for the duration of the skip:
private bool _skipped;
private void RootFrame_Navigated(object sender, NavigationEventArgs e)
{
RootFrame.Opacity = 100;
RootFrame.Navigated -= RootFrame_Navigated;
}
private void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
{
if (_skipped)
{
_skipped = false;
RootFrame.Navigated += RootFrame_Navigated;
}
if (e.NavigationMode == NavigationMode.Back &&
e.Uri.OriginalString.Contains("ThePage.xaml"))
{
RootFrame.Opacity = 0;
_skipped = true;
}
}
The code to determine when to make the page transparent is also different in my actual code, but I've added an implementation to the answer for illustration. This is almost identical to the code in the recipe linked in another answer, but doesn't involve needing to use a third party DLL.
I provided my own answer because I've seen the sources provided in the other answers before, but never paid attention to the code for hiding the root frame. I am not using the Non-Linear Navigation Service, just the code fragment for frame transparency (I don't need it to detect circular navigation as I'm well aware of the design choices I make in the app and can spot them myself :-)
This suffices as a workaround in the (currently) one case I have where I need to skip a page that doesn't make sense when going back. I'd like to think when Mango comes out I will be best placed targeting the latest version, so this code will soon be defunct.
Sources:
App Hub code recipe for Non-Linear Navigation
Non-Linear Navigation Service Blog Post
There is no way to do it before Mango, except with the flickering way you already know.
In Mango, you can use NavigationService.RemoveBackEntry.
And it's more a question of a bad application design, than anything else. You shouldn't require a immediate page for anything.
Your workaround should be to design a application structure that doesn't require any immediate pages.
How can I create a Popup balloon like you would see from Windows Messenger or AVG or Norton or whomever?
I want it to show the information, and then slide away after a few seconds.
Edit: It needs to be blocking like Form.ShowDialog() because the program exits after displaying the notification
You can use the notifyIcon control that's part of .NET 2.0 System.Windows.Forms. That allows you to place an icon for your application in the System Tray. Then, you can call the ShowBalloonTip(int timeOut) method on that. Be sure however to first set the text, and icon properties on the notifyIcon for it to work. Small code sample:
private void button1_Click(object sender, EventArgs e)
{
this.notifyIcon1.BalloonTipText = "Whatever";
this.notifyIcon1.BalloonTipTitle = "Title";
this.notifyIcon1.Icon = new Icon("icon.ico");
this.notifyIcon1.Visible = true;
this.notifyIcon1.ShowBalloonTip(3);
}
EDIT: Ok, so notifyIcon won't work for you. My second suggestion would then be to create your own control for this. Actually, I would use a form. A simple form, with no borders, and no control box and just have a timer running so you can set the Opacity for fade in/out. Then, you can easily get the bottom right of the screen using the Rectangle Screen.PrimaryScreen.WorkingArea. Then just show your form at that position.
Don't create a modal (blocking) balloon. Please. A big part of the design of these UIs is that they are not dialogs: they're transient, potentially non-interactive elements, intended to provide incidental information to a user without necessarily interrupting their workflow. A balloon that steals focus and blocks user input would be irritating at best - if you need a dialog, then use a dialog.
The .NET 1.1 Visual Basic Power Pack had a toaster control.