Hide cursor when idle - wpf

In my WPF app, I want to hide the cursor when it hasn't moved for a number of seconds.
If it is moved, I want to show it again.
Any ideas?

You could use MouseMove event like this :
Tested code:
myTimer = new Timer(3000);
myTimer.AutoReset = false;
myTimer.Elapsed += delegate { MouseExt.SafeOverrideCursor(Cursors.None); }; //Hide cursor
private void MyView_MouseMove(object sender, MouseEventArgs e)
{
myTimer.Stop();
Mouse.OverrideCursor = null; //Show cursor
myTimer.Start();
}
This is a helper for dispatching properly the call to override the Cursor:
public static class MouseExt
{
public static void SafeOverrideCursor(Cursor cursor)
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
Mouse.OverrideCursor = cursor;
}));
}
}
When the timer elapses the cursor is hidden. When its moved it reappears and timer is reset.

Related

WPF - Canvas won't update when BackgroundWorker is completed

I need to update my Canvas when BackgroundWorker is completed. When i update the Canvas through a button actionlistener it works perfect. But when i call my update function when backroundWorker is completed. The gui won't update.
The function that add items to the canvas:
public void AddItemsToCanvas()
{
int factor = 0;
cvList.Children.Clear();
foreach (ItemControl item in ItemControl.ItemsList)
{
cvList.Children.Add(item.updateName);
Canvas.SetLeft(item.updateName, 13);
Canvas.SetTop(item.updateName, factor + 10);
Canvas.SetZIndex(item.updateName, 1);
cvList.Children.Add(item.imageButton);
Canvas.SetLeft(item.imageButton, 180);
Canvas.SetTop(item.imageButton, factor + 13);
Canvas.SetZIndex(item.imageButton, 5);}}
The button that calls the update function:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
updateCanvas();
}
public void updateCanvas()
{
Service serv = new Service();
serv.SuperlinkCompartments();
//Check for updates and add them to a List of updates
Update up = new Update();
up.PropertyChanged += new PropertyChangedEventHandler(Items_PropertyChanged);
up.ShowUpdates();
}
public void Items_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
AddItemsToCanvas();
}
The Canvas updates perfectly when called from the button actionListener. But not working when the UpdateCanvas() is called from the BackgroundWorker event.
public void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
var item = dic3[(BackgroundWorker)sender];
int index = (int)item.controlButton.Tag;
item.Progressbar.Value = 0;
SystemInfo.SystemList[Update.UpdateList[index].SystemIndex].Version = Update.UpdateList[index].UpdateVersion;
lvSystems.ItemsSource = SystemInfo.SystemList;
updateCanvas();
}
I'm i missing something in the BackgroundWorker event function?
try using the `Dispatcher':
Application.Current.Dispatcher.Invoke(new Action(()=>
{
updateCanvas();
}), DispatcherPriority.Render);
then, inside your updateCanvas() method, add the following at the end:
cvList.UpdateLayout();

When to start the WPF Progress Bar

I want my app to show a running progress bar while doing some components checking. However, due to my lack of knowledge in Desktop app programming and WPF, I cannot find suitable place for it.
I tried to show the incrementing the progress Bar during the Window_Loaded(), ContentRendered() but with no luck.
Instead of showing the progressBar increases, it just show the final state of the progress Bar.
Here is the code
public partial class Loading : Window
{
public Loading()
{
InitializeComponent();
SetProgressBar();
this.Show();
CheckComponents();
}
private void CheckComponents()
{
System.Threading.Thread.Sleep(3000);
CheckProductionDBConnection();
pgrsBar.Value = 30;
System.Threading.Thread.Sleep(3000);
CheckInternalDBConnection();
pgrsBar.Value = 60;
System.Threading.Thread.Sleep(3000);
CheckProductionPlanning();
pgrsBar.Value = 90;
//MainWindow mainWindow = new MainWindow();
//mainWindow.Show();
}
private void SetProgressBar()
{
pgrsBar.Minimum = 0;
pgrsBar.Maximum = 100;
pgrsBar.Value = 0;
}
//more code down here...
Where should I put the CheckComponents() method?
You could put this code in an event handler subscribed to the Activated event. The one catch with this is that the Activated event is fired every time the window receives focus after having lost it. To get around this, the first thing you can do in your event handler is unsubscribe from the Activated event so that your code is executed only the first time the window is activated.
You also need to offload this work to a worker thread if you don't want the delay to block the main thread. If you do that, you'll have to invoke your calls to update the progess bar's value.
Here's some sample code to get you started:
public Loader()
{
InitializeComponent();
SetProgressBar();
this.Activated += OnActivatedFirstTime;
}
private void OnActivatedFirstTime(object sender, EventArgs e)
{
this.Activated -= this.OnActivatedFirstTime;
ThreadPool.QueueUserWorkItem(x =>
{
System.Threading.Thread.Sleep(3000);
CheckProductionDBConnection();
this.Dispatcher.BeginInvoke(new Action(() => pgrsBar.Value = 30));
System.Threading.Thread.Sleep(3000);
CheckInternalDBConnection();
this.Dispatcher.BeginInvoke(new Action(() => pgrsBar.Value = 60));
System.Threading.Thread.Sleep(3000);
CheckProductionPlanning();
this.Dispatcher.BeginInvoke(new Action(() => pgrsBar.Value = 90));
});
}
private void SetProgressBar()
{
pgrsBar.Minimum = 0;
pgrsBar.Maximum = 100;
pgrsBar.Value = 0;
}

How to stop ResizeEnd event when form is moved?

I write certain code in my form ResizeEnd event. Now problem is when form is moved by clicking and dragging on the caption bar, ResizeEnd event is fired and code is executed even though form size is NOT changed.
I gone through MSDN documentation for Resizeend event and it says that event will fire when form is moved (don't understand why this happens when the size is NOT changed).
For resolution I put the if condition to check if size is changed like below to stop execution of code on form move:
int Prv_Height; int Prv_Width;
private void TemplateGrid_ResizeEnd(object sender, EventArgs e)
{
if (this.Size.Width != Prv_Width || this.Size.Height != Prv_Height)
{
Prv_Width = this.Size.Width;
Prv_Height = this.Size.Height;
//Other code here when form resize ends...
}
}
So is there any way to stop ResizeEnd event to fire when form is moved? or any other better approach to solve the problem?
You could move your check for sizechange to a new baseform. On derived forms the resizeEnd event will then only fire if the size is actually changed.
public partial class CustomForm : Form
{
private Size _prvSize;
public CustomForm()
{
InitializeComponent();
}
protected override void OnShown(EventArgs e)
{
_prvSize = this.Size;
base.OnShown(e);
}
protected override void OnResizeEnd(EventArgs e)
{
if (this.Size == _prvSize)
return;
_prvSize = this.Size;
base.OnResizeEnd(e);
}
}
private void Form1_ResizeBegin(object sender, EventArgs e)
{
oldSize = ClientSize;
}
private Size oldSize = new Size();
private void Form1_ResizeEnd(object sender, EventArgs e)
{
if (oldSize == ClientSize)
return;
//Add Something
}

Silverlight 4:How to delay Mouseenter event

i have a situation where : User moves mouse over the image .
If user keeps mouse on that image for specific time ex. 2 seconds then only i have to proceed
further in mouseenter event otherwise don't.
I have already refred to http://forums.silverlight.net/t/86671.aspx/1 but looks like mine is different case.
One option is to use a DispatchTimer to determine the length of the mouse over.
bool isMouseOverImage = false;
public void Image_MouseEnter(object sender, MouseEventArgs e)
{
this.isMouseOverImage = true;
var timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(2);
timer.Tick += (object timerSender, EventArgs timerArgs) =>
{
if(this.isMouseOverImage)
{
// write your code
}
// stop the timer
timer.Stop();
};
timer.Start();
}
public void Image_MouseLeave(object sender, MouseEventArgs e)
{
this.isMouseOverImage = false;
}
If you have multiple images, you should create a re-usable Behavior and attach it to each image. I can define code for that if that would help.

WPF WebBrowser: How to set element click event?

I've figured out how to make everything red as soon as the page is finished loading:
private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
var doc = (IHTMLDocument2)webBrowser1.Document;
foreach (IHTMLElement elem in doc.all)
{
elem.style.backgroundColor = "#ff0000";
}
}
Now what if I want to make the element only change color when it's clicked? I see that elem has an onclick property, but it's type is dynamic so I don't know what to do with it. The documentation is pretty useless.
You could do it by using the HTMLDocumentClass instead of the IHTMLDocument2 interface:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)webBrowser1.Document;
doc.HTMLDocumentEvents_Event_onclick += new mshtml.HTMLDocumentEvents_onclickEventHandler(OnClickHandler);
}
bool OnClickHandler()
{
mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)webBrowser1.Document;
mshtml.IHTMLWindow2 win = doc.parentWindow;
win.#event.srcElement.style.backgroundColor = "#ff0000";
return false;
}
}
The above solution, has one drawback: the onclick event does not bubble, even though false is returned (i.e. clicking at hyperlinks does not navigate to other pages).

Resources