|
Looking forward to your CP article on your framework
best, Bill
"Science is facts; just as houses are made of stones: so, is science made of facts. But, a pile of stones is not a house, and a collection of facts is not, necessarily, science." Henri Poincare
|
|
|
|
|
Pete,
I've started using MVVM Light. I'm slowly pulling pieces of it into my implementation.
For example, I had written my own ViewModelBase class that encapsulates (is that the right word?) some common things that I needed for all of my classes. I changed the name of my base class and am now deriving it from Laurent's ViewModelBase, with all of my View Model classes still being derived from my modified base class. I was able to pull out some of the INPC stuff, etc. from my base class, and just use the MVVM Light implementation.
Likewise, I threw away my homegrown (based on some of your code in fact) RelayCommand class and am using the MVVM Light version. There was nothing wrong with the homegrown version, but Laurent's is a bit more flexible.
The Messenger class is the cat's a$$. I've found some good uses for that. I have not used the ViewModelLocator because I already had a scheme going that I like that was suggested to me by Collin Jasnoch, and it seems to be working well.
All in all, I feel I am getting there. Thanks for the suggestions and encouragement.
WE ARE DYSLEXIC OF BORG. Refutance is systile. Your a$$ will be laminated.
There are 10 kinds of people in the world: People who know binary and people who don't.
|
|
|
|
|
Tom, I'm delighted that I was able to help here. Laurent has done a fantastic job with MVVM Light, and it is a good one to get up to speed with. Good job.
|
|
|
|
|
Now if I could just get so that all of the views that I have designed weren't ugly... But that's another whole issue.
WE ARE DYSLEXIC OF BORG. Refutance is systile. Your a$$ will be laminated.
There are 10 kinds of people in the world: People who know binary and people who don't.
|
|
|
|
|
Personally, I prefer using the ViewModelLocator method vs. DataTemplates. Some people are the other way around.
I think the ViewModelLocator method is a lot cleaner and makes more sense. You load up a view and it should know how to do its own thing. Creating the VM first seems backwards to me.
IMO, you shouldn't be creating VMs by hand. You should leave that to the view locator and DI.
Also, the ViewModelLocator is 1 line in XAML vs. the DataTemplate method with is 3 lines of XAML + C# code to create the VM and set the DataContext.
|
|
|
|
|
I'll take your suggestions under advisement. For now, however, I'm going to leave that part of things alone. For this particular app, it is working well, and I have changed enough things around already. Maybe my next project. I need to get moving on this thing and get it finished up!
Thanks for the suggestions. I appreciate the input.
WE ARE DYSLEXIC OF BORG. Refutance is systile. Your a$$ will be laminated.
There are 10 kinds of people in the world: People who know binary and people who don't.
|
|
|
|
|
I feel the same way. It seems as though most of my time is spent on the architecture and implementing the pattern correctly. Then the actual core functionality of the application. But then again once all that is set up. Your life is made easier with unit testing etc.
|
|
|
|
|
Thats one of the main benefits. MVVM sort of makes you write really clean code by its nature. We've all written initialization functions that populate every control on the dialog in a single function whether they are shown or not. MVVM makes you populate the controls via very specific properties and makes you support lazy initialization. It also promotes seperation of controls code. I.e. lets say your dialog had 10 controls on it... we've all written MFC & Winforms code where IsEnabled & content properties are updated in 10 different places. MVVM makes you do it in a way that its all seperate and each control really only cares about itself. The other big benefit of course is that it moves a ton of code to the XAML.
|
|
|
|
|
I hear you. I started using MVVM without any framework and found I could get 90% of my code working that way. Reminded me of when I moved from C to C++ eons ago - the whole object oriented thing made no sense to me at first - now it's second nature.
/ravi
|
|
|
|
|
I felt the same way when I first started MVVM, then I stepped back and reconsidered what the puropose of MVVM really is...To segregate your data and business layers from the UI.
Read through this little example and you'll see my point at the end.
Take for example double-clicking a list item. You want to know in the ViewModel what list item was double-clicked. You can bind the list's SelectedItem in the XAML to a property on the VM, but that handles clicking a list item, not double-clicking. To handle this, you need to handle the event. But that's not easy in MVVM.
Here's what I do to handle something like this. In the View's code behind:
First the XAML
<ListBox x:Name="MyList"
ItemsSource="{Binding MyListItems}"
SelectedItem="{Binding MySelectedListItem}"
MouseDoubleClick="ListBox_MouseDoubleClick"/>
Then in the code behind:
public MainPage()
{
InitializeComponent();
this.DataContext = new MainPageViewModel();
}
then the event
private void ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ListBox list = sender as ListBox;
ListItem item = list.SelectedItem as MyBoundType;
var dc = this.DataContext;
dc.ListItemDoubleClicked(item);
}
This assumes a method in your VM called ListItemDoubleClicked that accepts a parameter of the type bound to your list.
The point here is this - you can write code in your views that references your VM becuase the view already knows aout the VM. Just don't write any data-related code in the view's code behind and you're not violating VMMV.
Everything makes sense in someone's mind
|
|
|
|
|
The whole point of MVVM is not to have code in your code behind. You want your view abstracted from the business logic as well as the data it is bound to. This approach of directly calling an event in the code behind, tightly couples everything. To conform more with mvvm, rather re-route the event through a command.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<ListBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding CurrentItemCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
You will need to download: System.Windows.Interactivity.dll for the expression blend sdk. To use this functionality.
I do believe that design patterns should only be used as a guideline for better development. not to be followed so strictly. But in this instance there is a better more mvvm type of solution. To what you suggesting with eventing.
|
|
|
|
|
The whole point of MVVM is not to have code in your code behind
I completely disagree.
The point of MVVM, or any design pattern for that matter, is separation of concerns, not "no code behind". No where in this does is mandate that you cannot have code in the code-behind.
And, the view is already coupled to the view model when you do
this.DataContext = new MyViewModel();
The code I posted did not make any reference to the business or data layers, so it did not violate the design pattern.
However, I do like the code you posted and agree that a command is the way to go. I posted my snippet as an example of calling into the VM from the view. Like I said, the two are already coupled, and the code didn't reference data or the BL, so there's no reason not to do it.
Everything makes sense in someone's mind
|
|
|
|
|
You just said it yourself separation of concerns. If your code is in the code behind how is it a separation of concerns than. Thus it is counter productive to what you trying to achieve out of the pattern. Yes I agree to an extent that you shouldn't ever follow a pattern completely and only see it as a guideline. However what you were trying to achieve can be done without hooking up an event and finding the selected item. Like I've said previously you can do what you were trying to do in a far cleaner way. As far as initializing the ViewModel for the DataContext. Well that can also be done in xaml. There are many ways to skin a cat remember that. The key is to find the most flexible solution when testing and going forward. The question I ask is what if you want to change your viewModel? you have to go into the code behind and instantiate another object. Why don't you rather use a IOC container in this scenario. So you can have a more decoupled soltuion.
|
|
|
|
|
In your example above, what is the "cmd" in
<cmd:EventToCommand PassEventArgsToCommand="True"
Thanks
Everything makes sense in someone's mind
|
|
|
|
|
A light MVVM framework called Galasoft
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
http://mvvmlight.codeplex.com/[^]
|
|
|
|
|
Dean Oliver wrote: The whole point of MVVM is not to have code in your code behind.
That's not quite true. The idea in MVVM is not to have code that knows about the model in the code behind of the view. If you want to have code that handles something like a window resize, for instance (it's just an example, and yes you could perfectly easily accomplish this with attached behaviors), it's perfectly acceptable to have this in the code-behind; as long as it doesn't have any model knowledge.
|
|
|
|
|
What's the difference?
Everything makes sense in someone's mind
|
|
|
|
|
"The Silverlight Business Application template creates a project that automatically includes many features that you typically want in a business application, such as controls to log in users and to register new users. The project created by the template is also set up to use Silverlight navigation, which means you can easily add new Silverlight pages for additional functionality.
By default, the Silverlight Business Application template enables authentication, roles, and profiles. The default authentication mode used by the template is Forms Authentication, but you can change the authentication mode to Windows Authentication by simply changing two configuration values. The procedure for making this change is provided here."
Read more about this here[^].
A Silverlight application, in contrast could be a simple web page application.
|
|
|
|
|
Hi
I have a menuItem in my application and I need to open a separate window (inside I have other controls).
I have just used Add from Visual, Add Window ..creates a new xaml and code behinde and I am able to use designer directly.
All I want now is to open this window from
MenuItem_Click
handler function.
Which are my options?
I have tried:
- first to put this window inside a Resource dictionary. It works but I can't use Designer when I open the myDictionary.xaml file.
And I think to declare resources like this is more for templates, styles etc..
<pre><ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window x:Key="pageOptions" Name="Test">
<Grid>
</Grid>
</Window>
</ResourceDictionary>
- I tried also to put the window inside a content presenter. Here I can use Designer on the xaml file but, I cant put a xClass in the window because it needs to be on the root. I cant put it also on the ContentPresenter element. So, I cant use code behind.
<pre><ContentPresenter Name="MyContent">
<ContentPresenter.Content>
<Window>Click Me</Window>
</ContentPresenter.Content>
</ContentPresenter>
|
|
|
|
|
I have found one way by dynamicaly loading XAML with the FileStream and XamlReader.
It has the disatvantage you have to make all your code behind.
Maybe there are other simpler solutions.
|
|
|
|
|
no, first time to hear about MVVM patern. I will start reading when I will have realy complex datas.
|
|
|
|
|
Hi
is that correct to call an element of a view from the viewmodel????
(i'm using MVVMLight)
example:
var grd = (RadGridView)e.Source; (e is KeyEventArgs)
|
|
|
|
|
It is not generally considered good practice for the viewmodel to have any knowledge of the view. generally, when you use the MVVM pattern, you should manipulate the underlying collections, which will be bound to the View in the XAML. You should provide more information as to what you are trying to accomplish, so that someone may help you more specifically.
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
Thanks for your help,
Can i use <x:code> in xaml for focusing on elements(like gridview) or getting the current item of a gridview or something like that in MVVM????
example:
viewmodel:
void BnbankPreviewKeyDownCommandExecute(KeyEventArgs p)
{
var grd = (RadGridView)p.Source;
var rowIndex = grd.Items.IndexOf(grd.SelectedItem);
if (((Keyboard.Modifiers != ModifierKeys.Shift) & (p.Key == Key.Tab & grd.CurrentColumn.DisplayIndex == grd.Columns.Count - 1)) || (p.Key == Key.Down))
{
if (rowIndex + 1 == grd.Items.ItemCount)
{
if (p.Key == Key.Tab & grd.CurrentColumn.DisplayIndex == grd.Columns.Count -1)
{
p.Handled = true;
InputSimulator.SimulateKeyDown(VirtualKeyCode.DOWN);
}
grd.CurrentCellInfo = new GridViewCellInfo(grd.Items[rowIndex], grd.Columns[0]);
grd.Focus();
grd.CommitEdit();
SaveBnbankCommandExecute(BnbankSelectedRow);
grd.BeginInsert();
}
}
}
view(Xaml):
<telerik:RadGridView x:Name="RadGridView1" ShowInsertRow="True"
ItemsSource="{Binding AllBnbanks}" SelectedItem="{Binding BnbankSelectedRow, Mode=TwoWay}"
CanUserFreezeColumns="False" AutoGenerateColumns="False" Height="300" CanUserInsertRows="True" ShowGroupPanel="False" FontFamily="Tahoma" FontSize="10" Margin="14,2,16,2">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewKeyDown">
<cmd:EventToCommand Command="{Binding Path=BnbankPreviewKeyDownCommand, Mode=Default,UpdateSourceTrigger=PropertyChanged}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataType="{x:Null}" UniqueName="Bnba01"/>
<telerik:GridViewDataColumn DataType="{x:Null}" UniqueName="Bnba02"/>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
|
|
|
|
|
The view should always render and style the data. the viewModel is purely for databound business objects, business rules, commands, and collections of items. Focusing would relate to the gridview so it should be part of the view. Current Item, selected item relates to a collection which is the data being bound by the viewmodel thus that logic should be in the viewmodel.
|
|
|
|