ViewModel into View - c#

Currently I'm learning C# with WPF. My mainapproach is to use the MVVM pattern the best I can but now I'm a bit confused.
In my Application for all my views I have a viewmodel:
private DruckviewViewModel ViewModel { get; set; }
public Druckview()
{
ViewModel = new DruckviewViewModel();
DataContext = ViewModel;
InitializeComponent();
}
Is this the suggested way to implement the ViewModel into the View or are there better ways to do it?

MVVM doesn't mean no code-behind.
MVVM is the pattern of separation of concerns. It helps to separate your application's architecture to the three parts(in order of appearance):
Model
View
ViewModel
Where Model is class containing your business logic.
View represents your view class which contains only view related logic(XAML and code-behind) It is Ok to have code-behind unless code contains only view's logic (for example in button click eventhandler you copy color of one textbox to another, which of course can be done in XAML, but from MVVM point of view it is not important)
ViewModel represents View's behavior without any reference to the View.
Notice that for example this property on my opinion will violate MVVM pattern, because Visibility is view related type
public Visibility MyVisibility { get; set; }
So dependencies between parts of MVVM goes like this:
Model doesn't know about anything
ViewModel know only about Model
View know about ViewModel
View ---> ViewModel ---> Model
I think for using MVVM is not important how tightly View bounded to the ViewModel. It is already bounded, because you use ViewModel's properties and commands.
Not bounding tightly (for example using interface as ViewModel) will give your possibility to test View without real ViewModel by creating own "design-time" viewmodels for example.
If your current solution works and satisfy your needs and you just starting with MVVM and WPF then continue with that until you meet need to fully isolate View from ViewModel's types

This will work, but it isn't really true to the MVVM pattern, as the View is now directly tied to the View Model.
Most existing MVVM frameworks use the concept of a View Manager. A class that creates a view from a view model instance, connects them together, and displays the view. You would end up with something like this:
DruckviewViewModel vm = new DruckviewViewModel()
ViewManager.Instance.DisplayViewFor(vm);
It would figure out, based on naming conventions, that DruckviewViewModel uses the Druckview. It would create the view, set the DataContextProperty, and make the view visible.
Without using one of these frameworks, this is a lot of work to build on your own, but this is considered a "Best Practice" pattern.
You may want to consider using an existing framework, a good list comparing their features can be found here.
BTW, if you are wondering how to get intellisense in the XAML designer without setting the DataContext in the constructor of the view. The proper way to do it is to add a design instance in XAML, with an attribute like this.
d:DataContext="{d:DesignInstance local:DruckviewViewModel}"

Related

c# mvvm how to pass model to viewmodel

I have read a lot about MVVM in the past, but I am not completely getting there.
I looked at MVVM Light framework and understood the pattern of the ServiceLocater to bind View and Viewmodel. But I didnt find anything helpful about the connection between the model and the viewmodel.
So far I know that the Viewmodel should have a private "Model" instance and some public properties to be read by the View. The Model should implement the INotifyPropertyChanged event to notify the Viewmodel, which can do something with the data and/or change its public properties and notify the view.
I hope I got it right so far. But: Where is the Model created? and how does the Viewmodel gets the Model? Does the Viewmodel creates it?
My Application gets data via bluetooth continously and process them in the background. At different process-stages it changes different Models. My first approach was a Singleton which holds all Models. The Viewmodel gets the Model from the Singleton and the Background-process can access the Model too. But I think that "pattern" is really bad.., but i cannot find any solution to do this "nice". I dont know how to share the model between the viewmodel and the background-process (businessLogic) properly.
I am glad about any help :)
As far as I know and use to do in our WPF projects - classical MVVM delegates Model creation on ViewModel. ViewModel should be Model-aware. Sometimes ViewModel could rely on ServiceLocator or DependencyInjection patterns to find out and create Model class (ie by interface).

Battleship in WPF using MVVM strucutre

I am completely new to WPF and MVVM, that's why I decided to start working on that. I am developing a Battleship game. If I create Canvas in my View, and create another canvas in ViewModel and bind them - everything works fine. However there is a problem. To begin with, I add Rectangles and TextBlocks to my Canvas to represent the grid. My "Field" Class (Model) is used in ViewModel for the logic to be done. And I want to have the property inside that class IsLegendHidden (bool). If I set that to true, then the method is called. In that method the linq looks for the textblocks related to my legend and then sets their visibility to hidden. It works fine, however having logic in the Model class is wrong in MVVM structure. But moving the algorithm to the ViewModel side will eliminate the ability to use class property "IsLegendHidden". But I want to have that property inside the model class. How can I solve that?
Your Model Class is free to implement INotifyPropertyChanged and it can notify the ViewModel when a particular property changes. This allows you to have a simpler model and get the logic done in the ViewModel.
You can also have a separate modeling of properties that are more focused on view concerns that the ViewModel can consult.
When using MVVM I like to try to separate things as much as possible. The model objects should just represent the concept they're modeling. The ViewModel is tied to a specific view so it will interpret or translate the model's properties into what is important to the view. You can have something on the Model that isn't 'IsLegendHidden', but that powers the ViewModel's 'IsLegendHidden' property.

Creating object of view class in ViewModel class in mvvm

I am working on mvvm in c# wpf, I have a little understanding of mvvm.
I am creating an object of my View class in My ViewMode classl.so is it violating mvvm pattern? and how ? it would be great if some one explains this in detail..
The whole point of the MVVM pattern is to maintain separation of the View (the display that presents controls to the user) from the Model (data, the business logic, data-access) and the ViewModel (the glue between the model and the view). The VM should not have to worry about UI (i.e. View) concerns, so creating and using a view within a viewmodel is violating that MVVM pattern.
A View is nearly always made up of UI elements, such as buttons or textblocks. A Viewmodel should be concerned with things like properties, such as a UserName, or a StartDate, or a WarningState. These VM properties are then bound (with DataBinding) to properties on UI elements within a view ... so the view has a dependency on the VM but not the other way around. Where the VM gets the data from to populate those properties in the first place is the model, or for data-entry maybe they'll all be blank to begin with and the application relies on the user entering data in the view.
You might want to bind the WarningState to a TextBox, for example, but equally you could bind it to a ComboBox. Or you could use a converter and bind it to the foreground colour of a rectangle, or the background colour of a UI element that is used for something else entirely different.
The point is that these are things the VM doesn't need to worry about: all it cares about is presenting data/state. It is up to the view how it deals with that information (or doesn't deal with it). In this way you could completely replace the view with a different version, and not have to change anything in your VM ... you have successfully separated your display from your logic.

How to set viewmodel property from code-behind using Viewmodel-first?

In my WPF (4.0) application I'm using Viewmodel-first pattern. Hence, my viewmodels are created first, then the views - using data templates. A working demo can be found here.
Now, from within the created views (code-behind), I need to modify a property of the viewmodel. In a View-first approach, I would simply access a named viewmodel instance. However, the Viewmodel-first approach does not allow for this. There is a viewmodel, but the view does not care what it is.
BAD:
Sure you can get hold of the DataContext and use it, but that effectively couples the view and t
the viewmodel.
private void MyView_Loaded(object sender, RoutedEventArgs e)
{
this.viewModel = DataContext as MyViewModel;
}
There has to be a recommended pattern for this. Commands? Messages? Please help!
Q: How do I modify (set a property) the active viewmodel?
Use Bindings to pass data from View to ViewModel and commands to active the ViewModel.
Commands should use a binding to a execute a Command on the ViewModel.
Messages should be used to communicate between ViewModels.
.
You can't do that. Otherwise View will be aware about View Model.
If this initialization is common across all view models, then you can define the properties/events in ViewModelBase and derive all view models from this class.
Q: How do I modify (set a property) the active viewmodel?
You need to use EventAggregator pattern for View-ViewModel communication.
You can use your favorite MVVM framework, and nearly all framework support EventAggregator (or MessageBus or Enterprise Bus).

Should I write classes for WPF controls?

I have a grid which I call let's say FooHistory. Now I need plenty of functionality related to that so I go ahead and I create a FooHistory class. Now I have a FooHistory class and a control.
In my MainWindow constructor I create a new instance of this class and pass the instance of this (i.e. the MainWindow) to the FooHistory class sort of like dependency injection. Then later when the FooHistory class wants to interact with the FooHistory control, I do things like this.mainWindow.FooHistory.Items.Add(...).
My question is that is this the recommended way to write WPF applications or am I missing some fundamental approaches?
We use for our programs the MVVM approach. While the details may differ from program to program MVVM is usually build with 3 main parts.
Model:
This is you data object. This may be business data like
class Account
{
string Name {get;set;}
string Address {get;set;
}
but can also be UI data like:
class Window
{
Point Position {get;set;}
Size Size {get;set;}
}
These objects are for holding data, nothing more. No events, no commands no methods (Thats one point where different interpretation of MVVM differ).
ViewModel:
This is to wrap the model and provide logic around the underlying model. This class is also used to convert a business model property into a view understandable property.
class AccountViewModel
{
public AccountViewModel(Account aWrappedModel)
{
}
string Name {get {return Model.Name;} }
AddressObject Address { get{ return new AddressObject( Model.Address ); }
}
View:
Is the wpf part this can be user controls, custom controls, windows, datatemplates etc.
Despite a common believe, its fine to have code behind for view otherwise you have to bend over backwords just because you heard that the view isn't allowed to have code.
The usual approach now is to create a model, one or more viewmodels and set these viewmodels as DataContext in your view. Sometimes you need a DataTemplate to display the given data, like a DataTemplate for our AccountViewModel.
<DataTemplate DataType="{x:Type AccountViewModel}">
<StackPanel>
<TextBox Text="{Binding Name}/>
<Button Content="Save" Command="{Binding SaveAccount}"/>
</StackPanel>
</DataTemplate>
This design makes heavy use of Databinding which is fundamental for MVVM and works quite nicely. Of course a couple of problems can arise like: How to handle Collection with models? How to handle events in the viewmodels coming from the ui? How to store my data?
But for these you find many resources here and in the web. But this answer should give you a rough overview of how i and alot other people work with WPF.
if most of your functionality is presentation-logic,
you can create a user control (by subclassing UserControl), and have a pair of .xaml and .xaml.cs files,
and put your presentation logic in the .xaml.cs file.
if most of the FooHistory class functionality is business-logic (or anything other than presentation), it's worthwhile to separate the FooHistory control from the FooHistory class, but in this case perhaps it's better to define an interface for the control, and pass the FooHistory instsance a reference to the control using this interface.
this way your FooHistory class needn't know anything about presentation - doesn't even need to know that it's WPF.
if you can avoid passing a tree of controls (such as SomeWindow.ParentControl.ChildControl.Items), it would make your life easier.
What you've described sounds like some kind of Model-View-Presenter pattern, a variant of MVC. As it is definitely a good pattern, especially for ASP.NET and WinForms, it doesn't utilise some core concepts of WPF.
Things you're missing are called Data Binding and Commands. On top of that features a new variant of MVC evolved - Model-View-ViewModel (MVVM), sometimes called Presentation Model. Roughly explained:
Your Window is called a View.
Youd Busines Logic is encapsulated in a Model.
You create a ViewModel class that exposes some properties which are View-specific representation of the Model. VM should also implement INotifyPropertyChanged to provide a way of notifying the UI about data changes. You expose operations the same way - by a property of type ICommand.
In View's constructor you write something like this.DataContext = new ViewModel()
Then you bind your View controls properties and ViewModel using {Binding PropName} syntax.
You might also want to check out some frameworks for MVVM like Prism, MVVM Light.
Here is some sample: http://rachel53461.wordpress.com/2011/05/08/simplemvvmexample/
Yes you can...... but there is no need to do that...........
the alternative way is.........
Make a dataset of data used in your grid......then import that whole dataset into your grid. so here no need to add items..... now you can filter,sort, add,remove or anything you want....

Categories