I am having issues updating the text in a tooltip for a system tray application. I have a timer updating several strings, but it will not update the notifyicon text. Here is what I have tried.
//This is in my main
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 5000;
aTimer.Enabled = true;
}
private static void OnTimedEvent(object sender, ElapsedEventArgs e)
{
ProcessIcon.GetDNS();
ProcessIcon.GetIP();
ProcessIcon.getMAC();
ProcessIcon.showALL();
Fixes.SetNotifyIconText(ni, ProcessIcon.showALL()); //This one will not update, the others update fine.
}//End part of my main
//This part is in another class for the notifyicon part.
public void Display()
{
// Put the icon in the system tray and allow it react to mouse clicks.
ni.MouseClick += new MouseEventHandler(ni_MouseClick1);
ni.Icon = new Icon("WhoAmI.ico");
Fixes.SetNotifyIconText(ni, showALL());
ni.Visible = true;
// Attach a context menu.
ni.ContextMenuStrip = new ContextMenus().Create();
}
I removed the timer and now call each function when the user hovers over the icon.
Related
I am a rookie to C#.
Here is the problem. I created a new thread to open my form1 twice in Program.cs.
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Thread secThread = new Thread(new ThreadStart(runForm));
secThread.Start();
Application.Run(new Form1());
}
private static void runForm()
{
Thread.Sleep(1000);
Application.Run(new Form1());
}
what I want is making two different users to do what they want such as clicking controlls &
mousemove in each form
Is it possible to add a cursor on both of these forms?
I mean "one form one cursor" in the form at the same pc.
Users dont need to do things across forms.
I have tried DrawCursorsOnForm in MSDN but nothing happened.(cursorImg is just a normal image.)
private void Form1_Load(object sender, EventArgs e){
Cursor cur = new Cursor(cursorImg.GetHicon());
DrawCursorsOnForm(c);
}
private void DrawCursorsOnForm(Cursor cursor)
{
// If the form's cursor is not the Hand cursor and the
// Current cursor is the Default, Draw the specified
// cursor on the form in normal size and twice normal size.
if (this.Cursor != Cursors.Hand &
Cursor.Current == Cursors.Default)
{
//// Draw the cursor stretched.
Graphics graphics = this.CreateGraphics();
Rectangle rectangle = new Rectangle(
new Point(100, 50), new Size(cursor.Size.Width * 2,
cursor.Size.Height * 2));
cursor.DrawStretched(graphics, rectangle);
// Draw the cursor in normal size.
//rectangle.Location = new Point(
//rectangle.Width + rectangle.Location.X,
//rectangle.Height + rectangle.Location.Y);
//rectangle.Size = cursor.Size;
//cursor.Draw(graphics, rectangle);
// Dispose of the cursor.
//cursor.Dispose();
}
What should I tried next?
I create a winform project with a single form with 4 textboxes and a button.
On button click, I perform the following:
Window1 w = new Window1();
ElementHost.EnableModelessKeyboardInterop(w);
w.Show();
Where window 1 is a Wpf window. Window1 has a single button on it and when that button is clicked the following occurs:
System.Windows.MessageBox.Show("HelloWOrld");
When you run the application the WinForm Form pops ups. If you hit tab it cycles through the 4 textboxes no problem. Then Click the button to open the WPF window. Click that button and popup the messagebox. Leave them open and then go back to the WinForm form you can no longer tab through the fields but you can type other characters. It appears as though the textboxes get the keystrokes but the form doesn't get them. I also get a system beep as though the model was getting the keystroke.
EDIT 9/9/2014 3:44PM
Hans responded in the comments and was correct. I tried describing a simpler case that would be easier for other people to reproduce that gave use the same symptoms. Our actual problem is that we have created a window base class that supports modal to parent capabilities. Here is the relevant code for our BaseWindow
public class BaseWindow: Window
{
[DllImport("user32.dll")]
static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
public void ShowModalToParent(Window frmParent, Action<bool?> callback = null)
{
IntPtr myHandle = (new System.Windows.Interop.WindowInteropHelper(this)).Handle;
EnableWindow(myHandle,
SetForegroundWindow(myHandle);
this.Closing += Window_Closing;
ShowInTaskbar = false;
Owner = frmParent; // Keep on top of parent
ClosedCallBack += callback ?? (p => { _modalDialogResult = p; });
var parentHandle = (new System.Windows.Interop.WindowInteropHelper(frmParent)).Handle;
EnableWindow(parentHandle, false); // Prevent events for parent
new ShowAndWaitHelper(this).ShowAndWait();
}
internal class ShowAndWaitHelper
{
private readonly Window _window;
private DispatcherFrame _dispatcherFrame;
internal ShowAndWaitHelper(Window window)
{
if (window == null)
{
throw new ArgumentNullException("panel");
}
this._window = window;
}
internal void ShowAndWait()
{
if (this._dispatcherFrame != null)
{
throw new InvalidOperationException("Cannot call ShowAndWait while waiting for a previous call to ShowAndWait to return.");
}
this._window.Closed += new EventHandler(this.OnPanelClosed);
_window.Show();
this._dispatcherFrame = new DispatcherFrame();
Dispatcher.PushFrame(this._dispatcherFrame);
}
private void OnPanelClosed(object source, EventArgs eventArgs)
{
if (this._dispatcherFrame == null)
{
return;
}
this._window.Closed -= new EventHandler(this.OnPanelClosed);
this._dispatcherFrame.Continue = false;
this._dispatcherFrame = null;
}
}
}
I'm sure this code was taken from a Blog/Forum post of some sort but am unable to find any reference to it in code. We want to keep the modal to parent but some how address the odd key press issue. To reproduce the issue replace the button_click in Window1 to call ShowModalToParent on a window that uses this as a base class.
I’m trying to show and hide a pop-up when certain events occur. The pop-up is appearing and disappearing properly, but all of its labels are blank. I originally was trying to populate the labels prior to showing the form, but I’ve commented-out all of that logic. The labels are all blank, but the space is properly allocated for each label (see screenshot).
my popup control:
public MyPopUp()
{
InitializeComponent();
}
my separate class:
MyPopUp _MyPopUp;
protected override void OnLoad(IServiceProvider myServiceProvider)
{
_MyPopUp = new MyPopUp();
}
protected override void WhenSomethingHappens() {
_MyPopUp.Show();
}
protected override void WhenSomethingElseHappens() {
_MyPopUp.Hide();
}
Here is part of my designer.cs file. I've only copy/pasted the code from one of the labels, but the other 5 labels on the form have nearly-identical code.
private System.Windows.Forms.Label label1;
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(58, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(41, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Some Label Text";
//
// MyPopUp
//
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "MyPopUp";
this.Text = "Some Text";
this.ResumeLayout(false);
this.PerformLayout();
}
You need to call Refresh() function to force every child control to invalidate, i.e. redraw, its client area.
For your case:
protected override void WhenSomethingHappens() {
_MyPopUp.Show();
_MyPopUp.Refresh();
}
This is happening because you are running the form modelessly.
If you want to you can check that your font/background colours are good etc. by running it Modally:
System.Windows.Forms.Application.Run(YourFormName);
then add the DoEvent line to your modeless call:
Form2 F2 = new Form2();
F2.Show();
System.Windows.Forms.Application.DoEvents();
and that should do it!
I have made a test and found a possibility to make the Label Text disappear. The Label Text disappears if the ForeColor is the same as the BackColor. From your Label-adding code, I see that you didn't specify these colors. WinForms Controls inherit a lot of properties from the parent control (in this case the Form itself), if they are not defined. This probably means that ForeColor and BackColor of the Form are the same and this propagates to the labels. Either change the ForeColor color of the Form or of the Label to fix this issue.
Try to invoke before showing the form, this way the form will be created in the main thread.
if (this.InvokeRequired)
this.BeginInvoke((Action)(() => //'this.' is the form
{
_MyPopUp.Show();
}));
I'm in trouble with a Marquee ProgressBar. I need to execute a method (refreshList()) to get a List<string>. Then I assign this List to a ComboBox, so ComboBox refreshes with the new Items. As refreshList() take 3 or 4 sec, I wanted to run a Marquee ProgressBar. But I couldn't. ProgressBar is ok, but ComboBox doesn't load new Items.
My refreshList() method:
private void refreshList(List<string> list)
{
albumList.DataSource = null;
albumList.DataSource = list;
}
I have the following code, it works fine:
private void changeDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
{
fbd.RootFolder = Environment.SpecialFolder.MyComputer;
folderPath = "";
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
folderPath = fbd.SelectedPath;
refreshList(N.getList(folderPath));
}
}
But I added a ProgressBar and wrote this code:
private void changeDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
{
fbd.RootFolder = Environment.SpecialFolder.MyComputer;
folderPath = "";
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
folderPath = fbd.SelectedPath;
bgWorker.WorkerReportsProgress = true;
bgWorker.RunWorkerAsync();
}
}
And I placed refreshList() in doWork() method:
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
refreshList(N.getList(folderPath));
}
But unfortunately this isn't working. Can anybody help me solving this problem? Thanks in advance.
You can use the MarqueeAnimationSpeed and Value properties of the ProgressBar control to stop and start the Marquee. There's no need to use WorkerReportsProgress* as you aren't incrementing a normal progress bar - you just want to "spin" the Marquee.
You can do something like the following:
public Form1()
{
InitializeComponent();
//Stop the progress bar to begin with
progressBar1.MarqueeAnimationSpeed = 0;
//If you wire up the event handler in the Designer, then you don't need
//the following line of code (the designer adds it to InitializeComponent)
//backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
}
private void changeDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
{
fbd.RootFolder = Environment.SpecialFolder.MyComputer;
folderPath = "";
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
folderPath = fbd.SelectedPath;
//This line effectively starts the progress bar
progressBar1.MarqueeAnimationSpeed = 10;
bgWorker.RunWorkerAsync(); //Calls the DoWork event
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = N.getList(folderPath); //Technically this is the only work you need to do in the background
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//these two lines effectively stop the progress bar
progressBar1.Value = 0;
progressBar1.MarqueeAnimationSpeed = 0;
//Now update the list with the result from the work done on the background thread
RefreshList(e.Result as List<String>);
}
private void RefreshList(List<String> results)
{
albumList.DataSource = null; //You don't need this line but there is no real harm.
albumList.DataSource = list;
}
Remember to wire up the RunWorkerCompleted event to backgroundWorker1_RunWorkerCompleted via the Properties bar, Events section in the designer.
To begin with, we start the ProgressBar's animation by setting the MarqueeAnimationSpeed property to a non-zero positive number as part of your successful folder selection.
Then, after calling RunWorkerAsync, the code builds your list in the DoWork method, then assigns the result to the DoWorkEventArgs, which get passed to the RunWorkerCompleted event (which fires when DoWork is finished).
In the backgroundWorker1_RunWorkerCompleted method, we stop the progress bar (and set it's value to zero to effectively return it to it's original state), and then we pass the list to the refreshList method to databind it and populate the ComboBox.
Tested using VS2012, Windows Forms, .Net 4.0 (with a Thread.Sleep to emulate the time taken for N.getList)
*WorkerReportsProgress, and the associated ReportProgress method/event are used when you want to increment the progress bar - you can tell the GUI that you are 10% done, 20% done, 50% done etc etc.
I'm trying to open a new form after clicking a node in a treeview.
In the first MDI form I have a treeview, when I click on a node in the tree view a 2nd MDI form is opened, but the first form keeps the focus. I want the new form to have the focus.
I have noticed the first form's _Enter event is firing as if something is setting focus back to the first form.
There is also a button on the first form that does the same function and it works great. I have a feeling the treeview has some special attribute set to cause the focus to come back to the first form.
Here is the code opening the form
private void tvClientsAccounts_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
OpenClientOrAccount(e.Node);
}
private void OpenClientOrAccount(TreeNode Node)
{
if (Node.Tag is Client)
{
frmClients frmC = new frmClients();
Client Client = (Client)Node.Tag;
frmC.Id = Client.Id;
frmC.HouseholdId = Client.Household.Id;
frmC.MdiParent = Program.frmMain;
frmC.Show();
}
else if (Node.Tag is Account)
{
frmAccounts frmA = new frmAccounts();
Account Account = (Account)Node.Tag;
frmA.Id = Account.Id;
frmA.ClientId = Account.Client.Id;
frmA.MdiParent = Program.frmMain;
frmA.Show();
}
}
Here is the designer code defining the treeview
//
// tvClientsAccounts
//
this.tvClientsAccounts.BackColor = System.Drawing.SystemColors.Control;
this.tvClientsAccounts.Indent = 15;
this.tvClientsAccounts.LineColor = System.Drawing.Color.DarkGray;
this.tvClientsAccounts.Location = new System.Drawing.Point(228, 193);
this.tvClientsAccounts.Name = "tvClientsAccounts";
this.tvClientsAccounts.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
treeNode9});
this.tvClientsAccounts.PathSeparator = "";
this.tvClientsAccounts.ShowNodeToolTips = true;
this.tvClientsAccounts.Size = new System.Drawing.Size(411, 213);
this.tvClientsAccounts.TabIndex = 23;
this.tvClientsAccounts.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.tvClientsAccounts_BeforeExpand);
this.tvClientsAccounts.AfterExpand += new System.Windows.Forms.TreeViewEventHandler(this.tvClientsAccounts_AfterExpand);
this.tvClientsAccounts.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.tvClientsAccounts_BeforeSelect);
this.tvClientsAccounts.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvClientsAccounts_AfterSelect);
this.tvClientsAccounts.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.tvClientsAccounts_NodeMouseClick);
Thanks for your help
Russ
Yes, TreeView is a bit of a pain that way, it restores the focus to itself. That's why it has the AfterXxx events, but there's no AfterNodeMouseClick event. The way to solve it is to delay executing the method, until after all event side-effects are completed. That's elegantly done by using the Control.BeginInvoke() method, its delegate target runs when the UI thread goes idle again. Like this:
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
this.BeginInvoke(new Action(() => OpenClientOrAccount(e.Node)));
}