Reputation: 21
If WPF MVVM is supposed to have no code behind, why does when you use the ICommand, do you need the DataContext property instantiated in the Window.xaml.cs code behind? I've watched and followed side by side YouTube WPF MVVM, data binding, ICommand, INotifyPropertyChanged videos and am confused.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel.VM_CalcRblAmt();
}
}
How to use the view model, model, command classes with data binding in the Window.Resource tag? If that is the correct mvvm pattern? Something like this below (but does not work)in the Window.Resource tag? I ask this because going side by side on WPF MVVM tutorials from different Authors, I do not see how to plug the view model, model, and Command classes into an xml namespace in the UI(Window in this case). For example below:
<Window...
xmlns:nsviewmodel="clr-namespace:Wpf_MVVVM_Rbr.ViewModel" />
<Window.Resources>
<nsrbrvm:RbrCoreViewModel x:Key="objRbrTemp"
<Button x:Name="btnRebalancer"
Command="{Binding CalcRbrAmtCommand}"
Content="Rebalance"/>
<TextBox x:Name="txtAmtDaily" Text="{Binding model_Rblr_Temp.AmtDaily, UpdateSourceTrigger=PropertyChanged}" />
</Window.Resources>
The above code, again, is not actually between the Window.Resources tags currently. It is in the UI XAML code outside the Window.Resources tags. Which currently does work. But does not the MVVM pattern require it in Window.Resources or Page.Resources tags referencing an xmlns namespace and giving it an x:Key="someKeyName" and using data binding inside the Resources tags?
So if this is the right MVVM practice, how do I put Window.Resources data binding, view model, command, and model classes together using data binding?
Thanks in Advance! Sincerely, Me
Upvotes: 2
Views: 1777
Reputation: 25
Thanks, StepUp!
Part one of your answer I got 1st and 2nd to work! I I'm using the 1st approach to avoid any code behind. The third I am sure works to, just maybe something I'm missing that you assumed I knew. But approach One is what I was looking for! Thanks. I'll devote sometime to trying to use and understand approach 4, UnityContainer.Registry type when I familiarize my self with that class. Part 2 of your appreciated answer, question, I have not reverse engineered and applyed yet. With the ICommand Interface, I have been using ICommand with what I took from a youTube tutorial video. But I'll return here to thank you once I put your code to use.
Upvotes: 1
Reputation: 38094
1. If WPF MVVM is supposed to have no code behind, why does when you use the ICommand, do you need the DataContext property instantiated in the Window.xaml.cs code behind? There are many approaches to set DataContext:
The first approach. In view:
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
The second approach. You should override OnStartUp() method of App.xaml.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow app = new MainWindow();
ProductViewModel context = new ProductViewModel();
app.DataContext = context;
app.Show();
}
}
The third approach. In constructor of Windows:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext=new MainWindowViewModel();
}
}
The fourth approach. You can set DataContext through DependencyInjection by UnityContainer. But DependencyInjection, Prism and UnityContainer are other questions and goes from this scope of the question. Just for example:
protected override void RegisterTypes()
{
unityContainer.RegisterType<object, ItemControl>("ModuleAUpper");
unityContainer.RegisterType<IViewModelItemControl, ViewModelItemControl>();
unityContainer.RegisterTypeForNavigation<ItemControl>();
}
2. How to use the view model, model, command classes with data binding in the Window.Resource tag? If that is the correct mvvm pattern? Something like this below (but does not work)in the Window.Resource tag?
Resources are just chance to store data. To set binding between property placed in viewModel and XAML, you should:
private string message="helloWorld";
public string Message
{
get { return message;}
set { message = value;}
}
and XAML:
Binding Button
in scope of MVVM:
<Button Command="{Binding ClickCommand}" Width="100" Height="100" Content="wefwfwef"/>
and ViewModel:
private ICommand _clickCommand;
public ICommand ClickCommand
{
get
{
return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), _canExecute));
}
}
private bool _canExecute;
public class CommandHandler : ICommand
{
private Action _action;
private bool _canExecute;
public CommandHandler(Action action, bool canExecute)
{
_action = action;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action();
}
}
Update:
I recommend you to read the best MVVM tutorial by Rachel Lim which I've ever read.
Upvotes: 3