Create a UserControl from a Model - Share ViewModel Property between UserControl - c#

I have created an UserControl that encapsulate two UserControl.
The first one is a "model" that can be changed by the User. It represents a ObservableCollection of TextBox. Each one of them is filled by the User.
My second UserControl will be a List of UserControl.
Each sub UserControl will be a list of textbox.
I want to be able to create my second UserControl by using the information of the first UserControl ==> Text in each Textbox used in tooltip of textbox.
So what I want is when the user add a field in the first usercontrol to be able to add the same field in each item of my second UserControl.
The black rectangle represents my model and the red rectangle represents my second usercontrol so the use of my model to create a UserControl.
Each UserControl owns his ViewModel.
Thanks in advance.

Hi please try the next architecture:
First User Control observable collection. The ObservableCollection supports event which will be raised when item will be added/deleted/etc. Submit on this event in your first user control view model.
Second User control let its view model be composed of ObservableCollections.
Share the EventAggregator (link here) between view models of your controls. First user control view model will be publisher and the second will be subscriber.
Each time when the observable collection of the first user control view model will be changed, publish the aggregator event to inform about the fact that this collection was changed.
Second user control will get the event and perform action (add/delete) on all its collection.
update
You can manage the sharing mechanism so that the EventAggregator will be the same reference, but the published object will have a key which represents a particular tab (for example the hash code of the tab), thus each subscriber will know if it have to response or not.
That's all. Try to perform that, I'll be glad to help if you will problems with the code.
Regards.

Related

WPF create a button for each view, which will set it as the content of a ContentControl

I have a WPF, MVVM program whose MainWindow is separated into a ListBox sidebar and a main part with a ContentControl. I want to create a functionality that will populate the ListBox with a button for each view that I have in my project and set its command such that clicking it will set the content of the ContentControl to the associated view automatically, i.e. so that I don't have to manually enter code when adding a new view. Something like iterate through all view files or something like that.
EDIT:
Perhaps I'm AGAIN not clear enough.
What I have and can do - type like a monkey "new Button, yadda yadda" every time I add a new view to my project.
What I want - write a piece of black magic that goes something like "There are 6 views in this project, I'll just make 6 buttons each such that, when clicked, will navigate to the appropriate view, without the guy who wrote me having to write any additional line of code any time a new view is added".
How can I achieve that and is it such a good idea, to begin with?
For instructional purposes, I'll be calling your "view" class View.
Create some sort of collection object (List<View>, ObservableCollection<View>, etc.) to store all of the Views.
Assign this collection to a dependency property. I'll call it Views.
Declare a dependency property for the selected/active view. I'll call it SelectedView.
Bind ListBox.ItemsSource to Views.
Bind ListBox.SelectedItem to View.
Bind ContentControl.Content to View as well.
With the above setup, the ContentControl will display whatever View is selected in the ListBox.

Passing objects between user controls in WPF

I have got an application that contains a series of input fields(TextBoxes, ComboBoxes etc.) When a button is clicked the user inputs are initialized into a new custom object. The content of the window is then replaced with a new UserControl (So I now have a blank view to display new information on).
I want to bind some of the method outputs from the object created in the first view, to text boxes in the new User Control which has been displayed.
the new object is created when the button is clicked so isn't initialized at the start.
But the obvious error is that the newObject I made in the first view doesn't exist in the context of the second view
Hope that sort of makes sense
any help appreciated
Instead of replacing the UserControls you can just Hide/Show them, this way you can access them in your other views.
But this is not a very good design and will be problematic in case a lot of controls are there in your window. Better approch would be to use MVVM and save the output of views in the MVVM properties etc.

Updating a control from another control child

I have some problems trying to update components of surface elements. I dont know if my approach to the problem is wrong, since I'm new to the topic.
My point is represented by the following diagram
According to the option that is selected in the menu, load different user controls as only child of StackPanel but i'm habing problems for update the Listview from loaded user controls, example: when I save a new item I need to recharge the list of items in the ListView
MVVM would be a good pattern here. If you have a problem passing data between controls - why not introduce them on top of unified data layer? Consider this:
Three radio buttons in your Menu, each one's IsChecked property bound to Visibility property of your respective UserControl.
StackPanel holding all three UserControls
ListView bound to ViewModel's List<Item>
Each of your UserControls bound to ListView.SelectedItem: one of them using TextBlock for read-only, one using TextBox for editing. Third one would create new item in your List<Item>. You would have to create ItemTemplate for each or create one UserControl (since they look very much alike) and use DataTemplateSelector.
If you're not familiar with MVVM here is a good start. You can also use one of the existing frameworks like MVVM Light
You can create an event on your child
public delegate void HandleNAMEOFYOURHANDLEEVENT();
on your child class
public event HandleNAMEOFYOURHANDLEEVENT yourInstance;
to use it on your child class
if (!ReferenceEquals(yourInstance, null))
{
yourInstance();
}
and you declare it on your parent like other event.

How can I store previous wizard pages?

Actually i am trying to do a Wizard control. In which i have load 3 pages dynamically when click the next button. When i click the next button i need to store the page details so i have created a dictionary to store the usercontrol. Is there any other suggestions to store the previous page details.
There are many ways to achieve your requirements. This is what I would do, which I think is very inline with the MVVM design pattern.
Define a ViewModel class that contains all the variables that you want to collect (regardless of the partition to pages.
Add a public property named 'currentPage'.
Define the frame of the wizard. Probably a <Window> element, with a StackPanel. The Window would have a title at the top, and an area at the bottom for the 'prev' and 'next' buttons (and 'finish' if you want to).
In the main area of the StackPanel put a and bind its DataContext to the ViewModel
In the ViewModel create a Next and Pref commands (use Prism DelegateCommand, or implement your own lightweight version that derives from ICommand.
6/ Also, bind the 'Finish' button to a command, with the appropriate CanExecute logic (have you collected enough data?).
The Next and Prev 'CanExectue' logic would look at currentPage. e.g. the Prev command CanExecute will return false when currentPage is 0.
You'll have 3 different data templates, one for each page. Each data templates will present different subset of properties you want to collect at that page. Bind the UI controls to properties at the ViewModel, and have the binding mode two way.
Derive your ViewModel from INotifyPropertyChanged, and have all the setters to fire the appropriate notification. It is required for at least the currentPage property, but for the completion of the solution do it for all properties.
In the Next and Prev command Execute method will modify the currentPage property (the Setter should fire notification). The view will update automatically.
For the main area ItemControl, implement a WizardTemplateSelector derived from DataTemplateSelector. Define it as a resource, and assign the ItemControl.ContentTemplateSelector using {StaticResource} binding.
If you want to, you can also have a List control at the left side of the Window, with the Selected Item Index bound to the current page.
EDIT (Explainer): The basic idea is to have a single ViewModel, which can be Viewed in several different Data Template, depends on the current page.

How to relay bindings from a Parent element to a Child element's data context?

I have a scenario where I have user controls on TabItem of a TabControl in the view. These user controls are individually bound to separate objects in the ViewModel. What I need is these controls to pass through to their bound object, the IsSelected property value of the parent TabItem.
Any ideas on how to do this kind of relay binding?
Why not have your ParentViewModel track the SelectedIndex of the TabControl, instead of tracking individual IsSelected values?
If that doesn't work, usually I use something like Microsoft PRISM's EventAggregator or MVVM Light's Messenger to broadcast messages to other interested ViewModels.
In this example, I would still bind the SelectedIndex to something in the ParentViewModel, and anytime that changes I would broadcast a SelectedTabChanged message. The individual child ViewModels that are interested in such information would subscribe to these messages, and perform whatever logic was needed based on if the selected tab is the one they belong to.

Categories

Resources