WPF and events from dynamically created controls - wpf

I need some help to implement a common behavior in some controls.
In my WPF application, I have a main form that contains a panel and a button:
Ok
The button will run a Save method when clicked.The Save method reads some data from the form and saves the data to a database.
The panel is populated with dynamically created controls (such as textbox, dropdownlists, etc). The main form instantiates a MainViewModel class. This MainViewModel class instantiates a class called UIFactory. So we have 3 levels here.
In the UIFactory class the controls is being created. The Panel from the main form is sent as a parameter to a method in the MainModelView class called GenerateUI. This GenerateUI method in the MainViewModel class calls a GenerateControls method on the UIFactory class that takes the same panel as a parameter. The GenerateControls method in the UIFactory class then adds dynamically created controls on the panel.
What I want to achieve is that whenever the user hits ENTER when he is typing in one of those dynamically created controls e.g a textbox, I want that behavior to be the same as clicking on the button in my main form. But how do I do that? I thought of implementing Routed events on my controls, but I can't figure out how to do it. Could you please advise me on how to achieve my goal?
Best Regards,
OKB

Maybe the Keyboard.KeyUp attached event might help you. You could set it on the main panel which contains the dynamically created controls and then perform the save operation if the pressed key was the ENTER key.

I did manage to create a work aroind to my problem:
What I did was to create a custom user control(let's call it a container). This control is hosted in my wpf application using the WindowsFormsHost instead of the panel. Then I add the dynamically created user control to my new custom user control (the container) and add a KeyEventHandler on each child control's KeyUp event.
I created a custom event and event handler in my container that will catch all KeyUp event from the child controls, check if the e.KeyValue == 13 (ENTER) and then raise my custom event from the container that will be handled in my wpf form. Ugly as h*ll, but it works.

Related

Single Command to call different commands in different View Models

Putting my requirement in very easy steps. Searched a lot on web but got very confused.
I got a Main Window (.xaml)
I got a Menu control, with Save option (a user control)
I got 3 more user controls (.xaml) in the same Window inside the Tab Control (with 3 tabs).
Each user control has data entries and has its own View Model class with Save() methods to save the data (implemented ICommand and INotifiyPropertyChanged in view model).
Now, if I have save button in individual usercontrol (inside the tabs) it works fine (I used commands for achieving this). But, I need the, Save to work, just clicking the "Save" on the menu, which is also a usercontrol and is inside the Main Window. The Menu save should act like a common Save for all the 3 user controls.
So the Menu should be now smart to identify which is the active usercontrol (probably based on the tab changed event or something else) and accordingly fire the Save() method for that usercontrol in the ViewModel.
Have you considered using Event Aggregator to accomplish communication between parts of your application without tightly coupling them.

WPF loading grid child based on treeview click

I'm developing a WPF C# app where I have a tree view control and if the user clicks on a node in the tree, a node-specific detail 'form' appears in a named Grid somewhere else in the form. If you click on a different node in the tree, the displayed detail form checks if the contents are saved, is dismissed, and a new detail form appears in it's place.
What I need is some starting advice. Can I still implement the forms as standalone xaml, then put some some of 'container' in the grid that I throw the form into as a child? Or just add the form as a grid child somehow. How do I programmatically load the form I want in the grid and communicate with it?
Thanks for any assistance!
Corey.
Use an event aggregator design pattern, see here for details:
http://martinfowler.com/eaaDev/EventAggregator.html
You can then have some other code which listens for the node change clicks via the event aggregator and response accordingly. This will decouple your code and make it more testable.
Am assuming you are using mvvm?
If not read up on it - will make it easier.
then you have your form with the treeview on it, bound to its itemsource on the view model.
Usually an items control like a treeview will have a selecteditem property on it.
Bind that to a property on your viewmodel which is of the type of objects contained in your treeview. Call this for example CurrentlySelectedItem.
Your details 'form' can be a control or whatever you want on the same form.
Now depending on how complete your object is - you have at least two options. If your object in the treeview has all the data you need already, then just bind the details to CurrentlySelectedItem.
Obviously it must implement INotifyPropertyChanged to tell the binding system to update the values.
If the object doesn't have enough info, then on the setter of CurrentlySelectedItem you can then fire a method to load the full object and then bind the details to that full object.
Alternativley, another popular approach, you could have the details form as a self contained control that subscribes to a message and when it recieves the message with the key of the treeview object, it loads the required info.

Closing WPF dialog box from contained UserControl

Hi I have a WPF application with various UserControls that contain key functionality. I want to be able to show say a FileManager UserControl in a tab on the main application, or have a dialog pop up when required, that contains the same UserControl.
It seemed like a good idea to create a modal Window and set its Content to the FileManager Usercontrol. But when I am finished with it, I am not sure how to close the containing Window, using a button on the UserControl. Is there an elegant way of doing this without having to store a reference to the Window in the UserControl?
Thanks for any advice!
Create an Event which is called when the respective button on the user control is clicked. That way, the containing control can react to the event in the appropriate manner. For example, a dialog could just close itself.
Is closing a window something that is integral to the functionality of the control in all the contexts where the control is hosted? E.g Does closing a window apply to the case where the control is hosted in a tab of the main app?
If not then you might be better off separating window closing code out of the UserControl in into the window/dialog that is hosting it - using events or whatever to tie the two together.

Dynamic child user controls MVVM

I have a user control on a page and I'd like to load another custom user control within it's grid. However I want the user control type to be dynamic - e.g selecting "Calculator" from a drop down list would display my custom calculator control and selecting "Currency Converter" would load my currency converter. Can anybody help?
By the way I am trying to stick to MVVM.
Thanks in advance.
One way is to define multiple DataTemplates one for each child. As user selects the option set the corresponding ViewModel to a ContentControl's DataContext present in parent view and framework will pick the corresponding view for you.
John Papa has written a great blog post on exactly how to do this here.
The basic strategy is to instantiate a new instance of a class that derives from UserControl once selected from the drop down.
In other words, the SelectionChanged event of the drop down list could be handled and a new UserControl object created based on the selected item.

Pass a value from child to parent in Silverlight

I am working on Silverlight project.
I added a custom user control (Say, control1) which has a text box and button to a xaml page (Say, Page1).
Now what I want to do is when users clicks on the button, i want to pass the value in the textbox to Page1 and do something.
So basically, I am looking for a way to pass back a value from child to parent page in Silverlight.
Thank you.
You should look into the Model View ViewModel (MVVM) pattern. It works very well with WPF and Silverlight.
http://en.wikipedia.org/wiki/Model_View_ViewModel
http://karlshifflett.wordpress.com/mvvm/ (lots of good information and demos)
You can do this through binding. Bind the Text value of the TextBox to a string property in your ViewModel and use that property throughout the code.
All the controls within your user control are accessible within your main page. If possible, write the click event of the button within the main page and you'll be able to access any control's property. Hope that work for you.

Resources