I have a C# solution with multiple WinFrom projects, and in this solution, I have a WPF project also.
When I start a WinForm project as a process inside MainProject, it runs perfect and I can debug it without any problem. But when I want to start WPF project as a separate process inside MainProject, I can't debug it.
I use Child Process Debugging Extension for debug child processes.
My code for start child process :
Process.Start(new ProcessStartInfo()
{
FileName = System.Reflection.Assembly.GetAssembly(typeof(UI.Export.DTO.Launcher)).Location,
WorkingDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetAssembly(typeof(UI.Export.DTO.Launcher)).Location),
Arguments = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(launcher))),
});
I also add both WinForm and WPF projects to Child Process Debugging Settings!
Thanks in advance :)
I would
subscribe an Application.Startup
put a blocker to the event handler of Application.Startup
do attach to the process, while wpf application is hanging in the
blocker part.
public partial class YourWpfApp : Application
{
public YourWpfApp()
{
Startup += YourWpfApp_Startup;
}
private void YourWpfApp_Startup(object sender, StartupEventArgs e)
{
System.Threading.Thread.Sleep(50000);//Attach to the process, while waiting here.
Startup -= YourWpfApp_Startup;
}
}
Related
In my WPF application, I have a single Main window with a Grid. The Login and Shell are 2 separate UserControls added as children to a grid. I need to find out when the Shell is loaded and start a timer from the Main window.
I just need to know as to what event is raised when a UserControl is added using Grid.Children.Add method, so that I can check if Login is loaded or the Shell and start the timer.
I'm not quite sure what you're trying,
but it sounds like you're looking for the Load event:
UserControl MyControl = new UserControl();
MyControl.Loaded += new RoutedEventHandler(MyControl_Loaded);
public void MyControl_Loaded(object sender, RoutedEventArgs e)
{
if (((UserControl)sender).IsLoaded)
{
..... do something
}
}
Hope it helps
I use a browse for files dialog to allow a user to select multiple images. If a lot of images are selected, as expected it takes a bit. Below is an example of what I do with the selected images. I loop through the filepaths to images and create an instance of a user control, the user control has an Image control and a few other controls. I create the instance of this control then add it to a existing stackPanel created in the associating window xaml file. The example just below works fine, but I'm trying to understand BackGroundWorker better, I get the basics of how to set it up, with it's events, and pass back a value that could update a progress bar, but because my loop that takes up time below adds the usercontrol instance to an existing stackPanel, It won't work, being in a different thread. Is BackGroundWorker something that would work for an example like this? If so, what's the best way to update the ui (my stackpanel) that is outside the thread. I'm fairly new to wpf and have never used the BackGroundWorker besides testing having it just update progress with a int value, so I hope this question makes sense, if I'm way off target just let me know. Thanks for any thoughts.
Example of how I'm doing it now, which does work fine.
protected void myMethod(string[] fileNames) {
MyUserControl uc;
foreach (String imagePath in fileNames) {
uc = new MyUserControl();
uc.setImage(imagePath);
stackPanel.Children.Add(uc);
progressBar.Value = ++counter;
progressBar.Refresh();
}
}
below this class i have this so I can have the progressBar refresh:
public static class extensionRefresh {
private static Action EmptyDelegate = delegate() { };
public static void Refresh(this UIElement uiElement) {
uiElement.Dispatcher.Invoke(DispatcherPriority.Background, EmptyDelegate);
}
}
Check out this article on
Building more responsive apps with the Dispatcher
Now that you have a sense of how the Dispatcher works, you might be surprised to know that you will not find use for it in most cases. In Windows Forms 2.0, Microsoft introduced a class for non-UI thread handling to simplify the development model for user interface developers. This class is called the BackgroundWorker
In WPF, this model is extended with a DispatcherSynchronizationContext class. By using BackgroundWorker, the Dispatcher is being employed automatically to invoke cross-thread method calls. The good news is that since you are probably already familiar with this common pattern, you can continue using BackgroundWorker in your new WPF projects
Basically the approach is
BackgroundWorker _backgroundWorker = new BackgroundWorker();
// Set up the Background Worker Events
_backgroundWorker.DoWork += _backgroundWorker_DoWork;
_backgroundWorker.RunWorkerCompleted += _backgroundWorker_RunWorkerCompleted;
// Run the Background Worker
_backgroundWorker.RunWorkerAsync(5000);
// Worker Method
void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Do something
}
// Completed Method
void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Doing UI stuff
if (e.Cancelled)
{
statusText.Text = "Cancelled";
}
else if (e.Error != null)
{
statusText.Text = "Exception Thrown";
}
else
{
statusText.Text = "Completed";
}
}
Using a BackgroundWorker alone won't solve your issue since elements created during the DoWork portion will still have originated from a non-UI thread. You must call Freeze on any objects you intend to use on another thread. However only certain UI objects will be freezable. You may have to load in the images as BitmapImages on the background thread, then create the rest of your user control on the UI thread. This may still accomplish your goals, since loading in the image is probably the most heavyweight operation.
Just remember to set BitmapImage.CacheOption to OnLoad, so it actually loads up the image when you create the object rather than waiting until it needs to be displayed.
I got my hands om MEF for a week now and I am trying to build up a WPF application that loads imported controls from MEF.
I created a WPF application project and removed the default window and application start up URI. Then I handled the application startup event to compose the application:
public partial class App : Application, IPartImportsSatisfiedNotification
{
{...}
private void App_Startup(object sender, StartupEventArgs e)
{
this.Compose();
}
public void Compose()
{
try
{
globalCatalog.Catalogs.Add(new DirectoryCatalog(extensionsDirectoryPath));
CompositionContainer container = new CompositionContainer(globalCatalog);
container.ComposeParts(this);
}
catch (Exception ex)
{
// Do something
}
}
{...}
}
Actually, when debugging and watching objects after imports are satisfied, everything has hierarchically composed fine like I wanted. But when I try to show up the MainWindow of the application an exception is thrown on MainWindow.Show() call:
"Specified element is already the logical child of another element. Disconnect it first."
Though my code in OnImportsSatisfied method seems fine as it is working when not using MEF mecanism:
public void OnImportsSatisfied()
{
Window mainWindow = new Window();
mainWindow.Content = this.importedControl;
this.MainWindow = mainWindow;
this.MainWindow.Show();
}
I insist on the fact that this works perfectly when not importing controls with MEF. What is surprising is that this code does not work too:
Window mainWindow = new Window();
//mainWindow.Content = this.importedControl;
this.MainWindow = mainWindow;
this.MainWindow.Show();
So I suspect that ComposeParts is doing a bit more than what it says as it is the only member acting on my actual application instance.
Hope someone can help me (Glenn?).
Thanks.
Edit:
I discovered that when I remove the IPartImportsSatisfiedNotification interface from my parts, no exception is thrown and the window shows up. But of course the window is empty as I need this OnImportsSatisfied method to set the DataContext of the window to its associated imported view model.
The sample applications of the WPF Application Framework (WAF) show how to use MEF within a WPF application.
I finally discovered that I was importing my WPF user controls by using the default ImportAttribute constructor, which in fact will make a shared instance of the class if the creation policy is not specified during export. And as many of my controls were implementing the same interface and I was binding them in my views, I was actually trying to add this shared user control instance to different visual elements, which is not permited by WPF (and so the exception).
I marked my imports using the RequiredCreationPolicy set to NonShared and everything got back in order! That was all about learning MEF...
I am calling Application.Current.Shutdown() from a class that is bound to xaml windows with ObjectDataProvider, but the application is not closing. Can anyone help me to understand why? My application is not closing completely after my main window is closed, it doesn't disappear from task manager's process list.
Try Environment.Exit(0) instead
Have you created any threads to do background processing? If you have, make sure to set the .IsBackground property on them, or they can keep the app running
Don't forget to add this:
private void Window_Closed(object sender, EventArgs e)
{
Application.Current.Shutdown();
}
Hope this helps.
If you have multiple windows or dialogs in your application, you may need to close each one explicitly.
Close dialogs with:
_myDialog.Close();
Close all windows:
foreach(var window in Application.Current.Windows.ToList())
{
window.Close();
}
I had a problem where the application would not shut down even when main window was closed. It turned out I had done Hide() on the splash screen instead of Close() so it was still lurking in the background keeping the application alive.
I had the same problem, the application process doesn't stop although the application closed.
In my case I opened a window from a BackgroundWorker (code below)
BackgroundWorker BG = new BackgroundWorker();
BG.DoWork += new DoWorkEventHandler(BG_DoWork);
StockMinWindow MinWindow = new StockMinWindow(null); -------- this is the problem
BG.RunWorkerAsync();
instanciate the window before running the BackgroundWorker seem not being the problem but by erasing the line the application closed correctly
I open my window from the BackgroundWorker but using the principal Thread (code below)
View.Dispatcher.BeginInvoke(new Action(delegate()
{
StockMinWindow MinWindow = new StockMinWindow(StockMinList);
MinWindow.Owner = View;
MinWindow.ShowDialog();
}));
Hope it helps.
I would like to be able to catch a child window focus event, in an mdi form.
If i loose focus to the entire mdi application, then click on a child, it works, but if I had two child forms open, I cannot catch the focus event when clicking between them.
I am using Dotnet Framework 2.0, and I need the code solution that will run fine on a windows 2000 machine, and up.
Thanks in advance for all help and advice,
-regards
Jeremy
I think you're looking for the Form.MdiChildActivate event. This event will be fired in your MDI parent form.
override the child forms Activated event.
sample code:
private void addChild(){
frmChild mychild = new frmChild();
mychild.Activated += FActivated;
mychild.MdiParent = this;
mychild.Show();
}
private void FActivated(object sender, EventArgs e)
{
MessageBox.Show("Activated one of the child.");
}