I'm having trouble understanding what you're saying, so my answer will be based on my interpretation. You should consider posting a sample (simplified) of what you're trying to do.
Up vote 1 down vote favorite 1 share g+ share fb share tw.
This is a question that extends from the originally posted here: Link to loading-xaml through runtime I'm working on a WPF MVVM application that loads XAML content dynamically from an external source, very similar as the answer in the post above. Here is what I got so far: My View declares an instance of the ViewModel as a resource and creates an instance of that ViewModel In my ViewModel constructor I'm loading a XamlString property coming from an external source (file or db..) In my view I have a button that user clicks after ViewModel finishes loading and in the click-event code-behind I'm deserializing the dynamically loaded XAML and add it to my grid. My question is, how can I eliminate code-behind and automate the logic so the View can render the new xaml section dynamically right after the ViewModel is done getting the XAML content and initializing the string property?
Should I use some kind of Messaging Bus so the ViewModel notifies once the property has been set so the View can add the new content? What troubles me is the fact that ViewModels do have a reference to Views and should not be in charge of generating UI elements. Thanks in advance!
Edit: Just to clarify: in my particular case I am not trying to bind a Business Object or Collection (Model) to a UI element (e.g. Grid) which obviously could be accomplished through templates and binding. My ViewModel is retrieving a whole XAML Form from an external source and setting it as a string property available to the View. My question is: Who should be in charge of deserializing this XAML string property into a UI element and add it programmatically to the my grid once my Xaml string property in the VM is set?
This sounds to me more of like a View responsibility, not ViewModel. But the pattern as I understand it enforces to replace any code-behind logic with V-VM bindings. C# .net wpf dynamic mvvm link|improve this question edited Jan 27 at 10:16 asked Jan 26 at 16:40Adolfo Perez466 75% accept rate.
This is exactly the problem Im facing and still no clear answer on how to address it: link I may have to try @ArmedMonkey 3rd suggestion through message subscriptions and callbacks – Adolfo Perez Jan 27 at 9:40 Another related and interesting question I just found: link – Adolfo Perez Jan 27 at 9:49.
I'm having trouble understanding what you're saying, so my answer will be based on my interpretation. You should consider posting a sample (simplified) of what you're trying to do. 1) I think you're misunderstanding what MVVM does.
MVVM is mostly a binding-based pattern. Your view model should be exposing properties containing business objects and your view should just be binding to those properties. If I am misunderstanding you, and that's what you are doing, then your problem is that your view needs to be aware of when the properties get updated (after you deserialize your xaml, etc).
There are two ways to do this: INotifyPropertyChanged interface on your viewmodel, or make your view model inherit from DependencyObject, and make the properties dependency properties. I won't go into details here, because this is a large subject that you should research on Google before making a decision. 2) Generally speaking, you shouldn't use click events inside your view if you're using MVVM.
Instead, create properties on the view model of type ICommand (and create ICommand implementations to match, or use an implementation of DelegateCommand (google it) which will allow you to use delegates to implement the interface. The idea is, your view binds to the property and executes the handler directly inside the viewmodel. 3) If you want to push information from the viewmodel to the view, then you should create an event on the viewmodel and subscribe to it in the view, but this is a last resort, only to be used in cases like displaying a new window, etc. Generally, you should be using binding.
4) To be more specific about what you're doing, you should be binding your Grid's ItemsSource property to some property on the view model. Note, the property on the view model should be of type ObservableCollection if you want to be able to add items and get instant updates. Hope this helps.
Thanks for your feedback, added some more details above. Hope it can make it clearer. – Adolfo Perez Jan 26 at 20:38.
I have a working solution now and I'd like to share it. Unfortunately I did not get rid of code-behind completely but it works as I expect it to. Here is how it works(simplified): I have my simplified ViewModel: public class MyViewModel : ViewModelBase { //This property implements INPC and triggers notification on Set public string XamlViewData {get;set;} public ViewModel() { GetXamlFormData(); } //Gets the XAML Form from an external source (e.g. Database, File System) public void GetXamlFormData() { //Set the Xaml String property XamlViewData = //Logic to get XAML string from external source } } Now my View: Basically I created a hidden TextBlock bound to my XAML String property in the ViewModel and I hooked its Loaded event to an event handler in the code behind of the View: private void tb_XamlString_Loaded(object sender, RoutedEventArgs routedEventArgs) { //First get the ViewModel from DataContext MyViewModel vm = content.
DataContext as MyViewModel; FrameworkElement rootObject = XamlReader. Parse(vm. XamlViewData) as FrameworkElement; //Add the XAML portion to the Grid content to render the XAML form dynamically!
Content.Children. Add(rootObject); } This may not be the most elegant but gets the job done. Like some people say, in MVVM there are some cases like this where little code-behind code is needed.
It doesn't hurt and also part of this solution still uses the V-VM Binding principles when using the VM to retrieve and populate the XamlString property and exposing it to the View. If we would like to Unit Test the XAML parsing and loading functionality we could delegate it to a separate class. I hope someone finds this useful!
I have a working solution now and I'd like to share it. Unfortunately I did not get rid of code-behind completely but it works as I expect it to. Here is how it works(simplified).
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.