In the application I am working with, if the user changes the value in a cell that is say positive to negative and the value is supposed to be positive at all times, the application forces the positive value. Right now, when this happens there is no alert shown to the user.
I would like to show a little unobtrusive alert, like the one that shows up when a new mail arrives in outlook, or something similar, so that the user can be alerted that the application did something on her behalf.
I tried using the NotifyIcon class to do this. But the problem with that class seems to be that the timeout on it doesn't work as expected. I want to show this alert for not more than 2s and the BallonTipText lasts for longer than 10s.
Is there a .NET class for this purpose?
If not, is there an alternate way to do something like this?
Using a notification icon for this case seems wrong to me. The user's attention is, when entering something into a cell, on the cell. If you display the notification on the lower right of the screen the user is very likely to miss it, or worse, it disrupts his work flow.
You might instead consider adding a balloon tip to the cell the user is editing. Kinda like the balloon tip Windows Explorer is showing on Vista and Windows 7 on renaming a file when you try entering a character that is disallowed in file names:
I have had this problem in the past. I gather that the timeout problem is because the operating system fixes a minimum value of 10 seconds and a maximum value of 30 seconds (or something like that).Edit Oh and this doesn't include time that a user is idle.Edit
I have used the following code in the past to get around this.
Just to clarify
Declare a public variable, say called ballonTipActive with a value of 0.
Insert a timer control disabled with 100ms delay and create an event from BalloonTipShown from the notifyicon control.
Then
private void ptNotifyIcon_BalloonTipShown(object sender, EventArgs e)
{
timer1.Enabled = true;
balloonTipActive = 0;
}
private void timer1_Tick(object sender, EventArgs e)
{
balloonTipActive++;
if (balloonTipActive == 40)
{
ptNotifyIcon.Visible = false;
ptNotifyIcon.Visible = true;
balloonTipActive = 0;
timer1.Enabled = false;
}
}
Setting the visible property to false then true gets rid of the balloon.
Related
First off I would like to say that I am kinda new to visual studio C# (2 months in) & I've studied other languages but I know the fundimentals & the project is somewhat done, its just this one feature I cant seem to get the hang of.
So I am trying to connect a trackBar to my WinForm application which is a SoundBoard.
It is not driven by Windows Media Player it is simply just some resources (Audio Files)
It is a really boring project its really nothing special but I really cant seem to get the code to work.
(Will provide the .cs files if necessary)
What I am trying to accomplish is that I want to make a trackBar that connects to the winForm app & lets the user control the volume of the WinForm itself.
I know I need to set the min and max values according to my needs at the beginning, like in the Form_Load event.
E.g. the volume control uses percentage 0 - 100%
Then I need to set min=0, max=100.
the thing is, I have no idea how to do it, I have never seen any code that makes any sence in this scenario.
Here is the code for the trackBar, or this is what I've gotten so far. I know its not much but I am really bad with trackBars.
(Sorry for my bad english, not my native tounge.)
private void trackBar1_Scroll(object sender, EventArgs e)
{
trackBar1.Minimum = 0;
trackBar1.Maximum = 100;
}
This is the code for the sounds being played with each button that is named differently.
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.Stream = Properties.Resources.cow;
player.Play();
There is no sense in modifying the Minimum and Maximum values within an Scroll event. Just set these values to 0 and 100 in designer (Properties window).
Then, you will be able to use this event and control the volume through it:
private void trackBar1_Scroll(object sender, EventArgs e)
{
yourSoundPlayer.Volume = trackBar1.Value;
}
As you haven't told what you use for playing a sound, I have assumed the Volume property. However, it may be another in your case.
I am trying to use a gamepad to control an application. It's not a game, just a plain application using Windows Forms. So it doesn't have a game loop/update process or anything like that. I wouldn't like to use XNA because I think it's a huge overload just to capture a button press.
I am experimenting with both SlimDX and SharpDX. As I understand, they are just wrappers for DirectX, right?
Looking at the documentation, it seems like there is no event for a button press. So I have been looking for an alternative. I have tried adding a timer (from the System.Windows.Forms.Timer class), and reading the state of the gamepad like this:
private void timer_tick(object sender, EventArgs e)
{
State s = controller.GetState();
stateLabel.Text = s.Gamepad.Buttons == GamepadButtonFlags.A ? "A" : "";
}
With a small enough interval between timer ticks (I'm using 10ms), I can see whether the button is pressed or not. However, I don't want to handle the button press multiple times should the button be held down - I need to make sure it has been released before handling the button press again. Between two ticks of the timer, I don't know if a button was pressed twice or if it was just being held down.
I thought about using the packet number in the controller state, but it will change at the slightest touch on an analog stick or shoulder trigger.
Help?
From what I can gather after reading you question over a few times is that you are wanting to log a button press only 1 time until it is released. You probably should use the packet number technique to keep track of any changes to the other input.
To get a single input from the button being held down as opposed to getting continuous input (1 as opposed to 11111111...etc) create an old state an a current state. Then compare the old state with the new state.
Something like this:
class Input
{
State old;
void GetInput()
{
State new = controller.GetState();
if (this.old.GamePad.Buttons == GamepadButtonFlags.A && new.GamePad.Buttons == GamepadButtonFlags.A)
{
// Do stuff that will be called only once.
}
this.old = new;
}
}
I'm using winforms in c#.
I simplified my app so that it just has a ListBox and a Button.
Here is my button click event:
private void button1_Click(object sender, EventArgs e)
{
for (long i = 0; i < 66000; i++)
{
listBox1.Items.Add(i.ToString());
listBox1.SelectedIndex = listBox1.Items.Count - 1;
}
}
When I run my app and push the button I see the ListBox updating and after a while (it varies entry 3041 or so) the program will appear to hang as it adds the rest of the entries once its done, the ListBox will appropriately refresh.
Why the hang? Is it just too much to handle? I looked at my cpu usage and memory didn't seem to be using that much so I'm not sure what the problem is.
You misinterpret what's going on. Your listbox will freeze after 5 seconds. That's when Windows steps in when it notices that you are not taking care of the normal duties of a UI thread. Your window is replaced by the so-called "ghost window" to tell the user you've gone catatonic and that doing things like clicking the Close button isn't going to have any effect.
The easiest way to tell that you got the ghost window is from its title bar, it says "Not Responding".
A version of it that will fare somewhat better:
private void button1_Click(object sender, EventArgs e) {
listBox1.BeginUpdate();
for (long i = 0; i < 66000; i++) {
listBox1.Items.Add(i.ToString());
}
listBox1.EndUpdate();
listBox1.SelectedIndex = listBox1.Items.Count - 1;
}
You shouldn't otherwise expect windows to behave reasonable when you do unreasonable things. And you shouldn't expect users to behave reasonable either when they are faced with this UI disaster. But they'll let you know themselves.
Every time you add an item, the memory it takes gets bigger, and since the items are in a dynamic list, the program may have to reallocate space.
Add to that the fact that you're probably using just one thread in that app (you're not using a background worker thread to update the list, right?) and you see why your app hangs. Windows forms always take a while when they have to update their controls... It's just that for normal, everyday use, they take milisseconds to update. For arcane uses like a list containing more than a few hundreds of items in the GUI, they'll take seconds or minutes to refresh, and you'll perceive that as hanging. Place the item handling in another thread, and you'll see that the form will update it's GUI pretty fast, but will take a long time between updates.
i am using this code under my form1_load
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(5000, "Welcome", "Hello " + User, ToolTipIcon.Info);
I even checked my registery and the value was 1. Why is the baloon not showing?
I do have a icon form my notify icon. and it is showing up. The Baloon is not though!
Looks like you forgot to set the Icon for it like this
notifyIcon1.Icon = SystemIcons.Exclamation;
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(5000, "Welcome", "Hello " + User, ToolTipIcon.Info);
Also please read for more inormation on issues with NI http://www.csharp411.com/notifyiconshowballoontip-issues/
You may need to post the rest of the code that's in your form's load event, but here's a couple of suggestions:
Make sure the form's Load event is actually hooked up.
Make sure you've assigned an icon for the notify icon.
Also, note that the balloon tip isn't guaranteed to show. See the Remarks section on msdn's NotifyIcon.ShowBalloonTip Method article:
Remarks Minimum and maximum timeout values are enforced by the operating system and are typically 10 and 30 seconds,
respectively, however this can vary depending on the operating system.
Timeout values that are too large or too small are adjusted to the
appropriate minimum or maximum value. In addition, if the user does
not appear to be using the computer (no keyboard or mouse events are
occurring) then the system does not count this time towards the
timeout.
Only one balloon tip can display on the taskbar at a time. Attempting
to display a balloon tip when one is currently displayed on the
taskbar causes the timeout value to be ignored. The behavior is
slightly different depending on the operating system and whether the
balloon tip is from another, or the same, application. When the second
balloon tip is from another application, the first balloon tip will
display for the minimum timeout value before the second appears,
regardless of the value of timeout. In most cases, if the balloon tips
are from the same application, the first balloon tip immediately
closes when another call to the ShowBalloonTip method is made. In some
cases the second balloon will open on top of the first balloon.
The title text will display in a bold font near the top of the
balloon.
Here is some sample code for what #MetroSmurf has already mentioned. Note that this.InitializeComponent(); must be called before the NotifyIcon is shown (usually in the form constructor).
public Form1()
{
this.InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
notifyIcon1.Icon = new Icon(#"C:\SomePath\MyIcon.ico");
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(5000, "Welcome", "Hello " + User, ToolTipIcon.Info);
}
Also ensure that windows is configured to allow notifications. In Windows 7 right-click taskbar, click Properties, Customize... in the notification area, tick the Always show all icons and notifications on the taskbar option, click OK.
I currently started to "port" my console projects to WinForms, but it seems I am badly failing doing that.
I am simply used to a console structure:
I got my classes interacting with each other depending on the input coming from the console.
A simple flow:
Input -> ProcessInput -> Execute -> Output -> wait for input
Now I got this big Form1.cs (etc.) and the "Application.Run(Form1);"
But I really got no clue how my classes can interact with the form and create a flow like I described above.
I mean, I just have these "...._Click(object sender....)" for each "item" inside the form.
Now I do not know where to place / start my flow / loop, and how my classes can interact with the form.
Pretty straightforward, actually (though I can sympathize with your confusion)...
1. Input
Have a TextBox and a Button. When the user clicks on the button, treat whatever's in your TextBox as your input.
2. Process Input
In a console app, the user is unable to do anything while you're processing input. The analogue to this in a Windows Forms app is to disable the mechanism by which the user can supply input. So, set your TextBox.Enabled = false and Button.Enabled = false.
3. Execute
Run whatever method you want to execute.
4. Output
Have some kind of message displayed on the form. This could be simply another TextBox, or a RichTextBox... whatever you want.
5. Wait for Input
Once your method from step 3 has executed, you've displayed the output in part 4, you can go ahead and re-activate your mechanism for accepting input: TextBox.Enabled = true and Button.Enabled = true.
So basically your code should like something like this:
void myButton_Click(object sender, EventArgs e) {
try {
myInputTextBox.Enabled = false;
myButton.Enabled = false;
var input = ParseInput(myInputTextBox.Text);
var output = ExecuteMethodWithInput(input);
myOutputTextBox.Text = FormatOutput(output);
} finally {
myInputTextBox.Enabled = true;
myButton.Enabled = true;
}
}
Basically, you can have your form provide a set of controls for inputting data (ie: one or more TextBox controls). If you have a button that the user clicks, and you want to process, just double click on teh button. This will give you an event handler like:
private void button1_Click(object sender, EventArgs e)
{
// Process Input from TextBox controls, etc.
// Execute method
// Set output (To other controls, most likely)
}
That's it - the "loop" goes away, since the standard Windows message pump takes its place.