I am trying to make a system tray application that loads on startup and pops a balloon text every 2 hours. If there is such an example its great.
I am looking to use.
WPF,
Timers,
Delegates, events
I am not sure if these are enough or do I need something more.
Thanks in advance.
I think you will be fine with those. All you need is actually a NotifyIcon and a Timer. I've accomplished similar this way, except I wasn't using WPF (I rather used the 'classical' Window designer).
The simplest way to let your app start on startup would probably be to put it into Startup folder in the Start menu, there's actually no need to use the registry.
First of all here is what you need about starting your application on system startup :
Lets say I have a checkBox and I want to start my application on windows startup if this checkBox is activated :
RegistryKey rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
private void checkBox_autoStart_Checked(object sender, RoutedEventArgs e)
{
rkApp.SetValue("Your Application Name Here",Assembly.GetExecutingAssembly().Location);
}
and about the deactivation of that you do the follwoing :
private void checkBox_autoStart_Unchecked(object sender, RoutedEventArgs e)
{
rkApp.DeleteValue("Your Application Name Here", false);
}
p.s : Your application name will appear on the task manager the way you write it up there
And about using a notify Icon , well actually WPF doesn't support a ready made one so either you use the Windows Forms Notify Icon or you use the one mentioned in a nother answer from codeproject.com
if you wanted to use the one that already exists in windows forms , you have to add a reference to System.Windows.Forms in your project
A windows service may be the best thing for running in the background, but it may be tricky to get access to the GUI from a service (I don't think it's trivial).
For a WPF desktop app to do a tray notification, see this project with demo and source code: http://www.codeproject.com/KB/WPF/WPF_xaml_taskbar_window.aspx
To get the notification every 2 hours, you can use a DispatcherTimer:
http://social.msdn.microsoft.com/Forums/en/wpf/thread/aaffea95-e735-492d-bd8a-2fdf7099a936
Related
I am in the process of writing a WPF application that hosts 10+ usercontrols I have written. What I would like to do is modify the code from "Wonko the Sane"'s answer in this post
Is there a way to show a splash screen for WPF application?
to dynamically show the name of these usercontrol dll's as they load.
I have not been able to find anywhere how to get the names of dll's as they load.
Any assistance would be appreciated.
Thanks, Jim
Sorry, but you won't be able to do that. The WPF Framework loads before your program starts executing. The best that you'll be able to do is to add the names of the relevant DLLs into a string collection and then loop through them, displaying each one temporarily. Even if you could display what was being loaded, the chances are that they'd actually load so quick that you wouldn't see anything anyway.
It's also worth pointing out that it is only really worth having a splash screen in a WPF Application if you have a real lot of initialisation loading to do. In that case, you can show what the application is doing, but you'll probably find that in most cases, the loading is still done too fast for the UI to update in time.
You can get the current application domain and then use AssemblyLoad event to get loaded Dll name.
AppDomain MyDomain = AppDomain.CurrentDomain;
MyDomain.AssemblyLoad += new AssemblyLoadEventHandler(SplashControllerObject.LocalEventHandler);
private void LocalEventHandler(object sender, AssemblyLoadEventArgs args)
{
//use sender.LoadedAssembly.FullName for DLL name loaded
}
I've been creating a WPF application that initially loads as a task bar icon and then when clicked opens an appropriate window. This was a prototype and I want to move over to Prism and having watched the (superb) videos by Mike Taulty (channel9.msdn.com/niners/mtaulty) I have the feeling that what I need to do is create an application with a custom bootstrapper that does all the service registration but does not create an initial shell but instead simply loads the modules and perhaps identifies a module to Run. Has anyone anyone done something similar, if so how much work am I in for?
OK I bit the bullet and just tried it. I should first state that I was using the Autofac version of the Bootstrapper.
I returned null to CreateShell
I marked the apps ShutdownMode="OnExplicitShutdown" in the declaration at the top of App.Xaml (important otherwise it closes the application when you close the last window)
I created a module (IModule derived) that loaded the WPF notify icon by Philipp Summi (http://www.codeproject.com/Articles/36468/WPF-NotifyIcon)
In response to a command from the context menu on this icon I simply create the window and it's view model and show it.
This all works just as I had hoped. The only thing I have yet to do is see how to use regions with these temporary windows although other articles appear to have this covered. I'm not convinced the Autofac bootstrapper gives me any great advantages but I had developed a very early prototype using Autofac and stuck with it because it went smoothly. I will probably go with Unity or MEF in the long run just to avoid compatibility problems and to allow dynamic module loading from external plugins.
I am working on WPF application. I got a scenario where I need to find a unmanaged popup window when it pops up and bring it to front of the application. I used user32.dll and following code snippet (something like) to achieve it:
private void SetPopupScreenForeground()
{
string popupTitle = "Popup Screen"
IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, popupTitle);
if (IntPtr.Zero != hwnd)
{
SetForegroundWindow(hwnd);
}
}
But when I installed my application in another machine, the code is not working. From internet, I found the reason being the code is running as a service and does not have access in the different machine. Is there any workaround for this issue?
Is there any way to find unmanaged window and bring it to front in WPF application without using user32.dll? Please help.
The issue is actually how Windows handles "desktops". Services run under a special desktop that has no ability to interact with the user's desktop. You will need to communicate using a shared object such as a named pipe.
Here is a duplicate question:
How to use FindWindow() from a service application?
If by service you mean Windows service then those normally can't interact with the Windows desktop at all, so it's not a question of using user32.dll or not.
When hosting WPF user controls within a WinForms MDI app there is a drawing issue when you have multiple forms that overlap each other that causes very distinct visual artifacts. These artifacts are mostly visible after dragging one child form over another one that also hosts WPF content or by allowing the edges of the child form to be clipped by the main MDI parent when dragging it around. After the drag and drop of the child form is completed the artifacts stay around generally but I've found that setting focus to a different application's window and then refocusing back on to my application window that it is redrawn and all is good again until the child forms are moved once again. Please see the image below which demonstrates the problem.
Those at Microsoft insist that the WinForms MDI is already a sufficient solution for MDI and doesn't need reinventing in WPF although I find it hard to believe they tried creating a WPF app this way because of the obvious shortcomings.
UPDATE: A few extra notes that I left out is that if I create these Forms without setting the MdiParent they are created as regular forms and this issue doesn't happen. This issue seems unique to the WinForms MDI scenario. Also I've currently running on Windows 7 Enterprise and I'm aware the results may be quite different on Windows XP but I haven't been able to test this.
UPDATE: I've found a few other related resources on this issue that I thought I should share.
elementHost repaint problem in MDI
application
elementHost repaint problem in MDI application on Tech Archive
It appears that another workaround is to revert to software rendering as opposed to taking advantage of hardware acceleration. This was the suggestion by Marco Zhou on the MSDN Forums.
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
this.Loaded += delegate
{
var source = PresentationSource.FromVisual(this);
var hwndTarget = source.CompositionTarget as HwndTarget;
if (hwndTarget != null)
{
hwndTarget.RenderMode = RenderMode.SoftwareOnly;
}
};
}
}
I've tested this and this solution seems to work very well and so far is the only solution that I've found for solving this problem within a FoxPro interop scenario which is very similar to the WinForms one I posted about originally. For now I'm planning to use my original Refresh on the MDI Parent solution for my WinForms project but then for my other native interop applications such as when my WPF controls are hosted in Visual FoxPro I'll use this solution. That is unless of course if a more elegant solution is discovered for either of the cases.
Also it's important to note that from what I'm aware software rendering is the only option on XP systems and normally Visual FoxPro nore WinForms normally take advantage of the same type of hardware acceleration that native WPF apps do on Vista OS and up. So using this option may not be as bad as it sounds when you do have to deal with interop. Currently I'm not aware of any related side effects when using this solution but if there are any those would have to be taken into serious consideration.
Well, I may have found a solution although it feels like a bit of a hack. It appears that if you call the Refresh method on the MDI parent whenver a child MDI Form is moved that the noted artifacts go away. Visually things appear a bit jittery when dragging a window but it seems much more acceptable than the example I showed in my original post.
private void Form1_Move(object sender, EventArgs e)
{
this.ParentForm.Refresh();
System.Diagnostics.Debug.WriteLine(string.Format("Form Moved to: ({0},{1})", this.Left, this.Top));
}
I've tried many combinations in the same vein such as refreshing just the child window that was being moved by calling methods such as Update(), Invalidate(), Refresh() and also I've tried these same methods on the MDI parent as well as Dispatcher.Invoke(DispatcherPriority.Render, ...) and InvalidateVisual() on my hosted WPF control but none of those other methods worked accept for calling Refresh() specifically on the MDI parent.
I realize that this probably isn't the optimal solution since I'm forcing the whole main application window to refresh every time a child window moves a few pixels but as for right now it's the only reasonable solution that I found that works. If anybody else has any alternative solutions or any improvements upon this I will gladly accept your answer instead.
Check video drivers and try disabling hardware acceleration. Most artifacts are caused by bad drivers, failing video card, or insufficient time to complete the refresh.
First troubleshooting step: Update video drivers. Obvious, I know.
I had similar issue, checking my video card settings (NVidia Control Panel) showed global setting set very high causing a longer refresh interval which may be aborted if taking too long. Setting my settings back to defaults resolved most of the issue. But I also run hashing programs which use the GPU intensely so this is likely the cause of my remaing artifact issue which is very seldom now and mostly shows its ugly face in Visual Studio.
Another troubleshooting step I ran across is to disable hardware acceleration for WPF, this can be done in 'HKEY_CURRENT_USER/SOFTWARE/Microsoft/Avalon.Graphics', or maybe an application can do it BUT this is only for troubleshooting; never set these within an application because it will disable for ALL WPF applications. I do not have this registry setting nor did I add it so I am not sure of the success with it, but many say this resolved their issue. Also note some applications have this option available, try disabling it if available.
Another troubleshooting step is to make sure the video card is a proper tier level for rendering. Any card that supports DX9 or greater should be sufficient, but other factors are involved (as is my case) so just because it is on the list does not mean it is adequate for your purpose.
Finally, you can use the Visual Profiler (part of Windows SDK), and other tools, to help determine what is going on more precisely with WPF lacking performance in relation to graphics ability.
Rendering Tier level notes and WPF Performance information --> http://msdn.microsoft.com/en-us/library/vstudio/ms742196(v=vs.90).aspx
Hope this helps someone.
--Ryan Strassburg
Your usercontrol or window loaded event ;
this.WindowState = System.Windows.WindowState.Minimized;
this.WindowState = System.Windows.WindowState.Normal;
it may seem bad solution. no need to hit your head against the wall.
A Turkish proverb says: the best code is the code is running :)
Im building a wpf app with the composite application block ("prism") V2, and Im having an issue where a user control that is injected by a module is very slow in rendering. The user control contains a datagrid with some 2000 rows in it and there is considerable lag in the control rendering to the screen. Initially I thought the slowness was due to the wpf toolkit datagrid control itself but this is not the case. When I move the control containing the datagrid (TestControl) out of the external module and into the shell project and load it straight from there the control renders immediately without any problems.
Im using the following code in the implementation of IModule in my module to inject the wpf user control into the shell
this.regionManager.RegisterViewWithRegion("mainRegion", typeof(TestControl));
Is there performance issues when loading controls from other modules in a prism app? Whats the most optimal way to load them in?
Thanks
the problem here seemed to be wpf being slow to update when the UI is being updated vai the dispatcher from a background thread. I took up the conversation on codeplex and got it more or less sorted.
http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=64113
It's likely this is an artifact of the lifecycle events. Your shell is going to display well before your modules start to load and register themselves. If you do this it will "appear" to take longer because your UI will appear with a big fat hole in it until the module initialization code fires.
A lot of the samples have you doing something like "Shell.Show();" in your CreateShell method of your bootstrapper, but you might consider moving the references to the Shell to a private member of your bootstrapper class and calling .Show() on it in, like this:
public class Bootstrapper : UnityBootstrapper
{
Shell shell;
protected override DependencyObject CreateShell()
{
shell = Container.Resolve<Shell>();
return shell;
}
protected override void InitializeModules()
{
base.InitializeModules();
shell.Show();
}
I tried this just now and it definitely felt like my app got a performance boost, so I think I'll make this change myself.
If your modules take a really long time to load, you also might want to show a splash screen between CreateShell and after InitializeModules.