ViewBag and ViewData ViewModel Properties
ViewBag is a ViewModel property and is one of the main advantages of Fluent MVVM.
Important:
ViewBag property isn’t mandatory, and you can choose when to use it and when not..
ViewBag greatly accelerates the development and allow us to focus on the business forgetting repeating task such as defining full properties and implement INotifyPropertyChanged.
S
This is a definition comparation with and without
ViewBag.
With
ViewBag> property just need the initialize ViewBag property. Without ViewBag> it is necessary write a full property and to implement and to call INotifyPropertyChanged interface>.
Pros and Cons
Pros
- It isn’t necessary to define properties we will just have to initialize them online.
-
It isn’t necessary implement
INotifyPropertyChangedinterface or callPropertyChanged eventin sets methods. - Accelerates development and makes it very much fun by removing repetitive boring tasks and creation of properties.
- The code is greatly reduced.
- The code is more readable.
-
We can choose with properties are
ViewBagorViewDataand which ones are not. We can mix them without a problem.
Cons
-
ViewBagcode> is adynamicproperty, so than we lost the intellense. If we use a property very much in aViewModel, this property isn’t candidate to beViewBagproperty and the good solution is created a standard property. This problem not exists in the more cases, because in theViewModelsclasses the vast majority of properties are used for move values to theViews. If we are very lazy, we can fix it with a casting. -
For non-string properties in
Two-Awaybinding may have problems with special string formats. We will be examples later.
Example
We will star preparing the project (view QuickStart section, to initialize). Install Nuget, create folders, add IoC configuration and AutoViewModel config.
We will centrate in
View and ViewModel classes implementation.
We will build a simple example of filter data. We have added a
Mock Repository for work data.
Add Code To ViewModel Class
using FluentMVVMExamplesDesc.ViewBag.Data; using MoralesLarios.FluentMVVM; using MoralesLarios.FluentMVVM.Infrastructure; using System; namespace FluentMVVMExamplesDesc.ViewBag.ViewModels { public class MainViewModel : ViewModelBase { private readonly IMockAlbumRepository _mockAlbumRepository; public MainViewModel(IMockAlbumRepository mockAlbumRepository) { _mockAlbumRepository = mockAlbumRepository; InitialViewBag(); } private void InitialViewBag() { ViewBag.PrincipalData = _mockAlbumRepository.GetData(); ViewBag.ArtistNameFilter = string.Empty; ViewBag.AlbumNameFilter = string.Empty; ViewBag.GenreFilter = string.Empty; ViewBag.ReleaseInitFilter = DateTime.Today.AddYears(-50); ViewBag.ReleaseEndFilter = DateTime.Today; ViewBag.NumCopiesInitFilter = 0m; ViewBag.NumCopiesEndFilter = 100000000m; } public SimpleRelayCommand FilterCommand => new SimpleRelayCommand(FilterExecuted); private void FilterExecuted() { var filter = new AlbumFilterInfo { ArtistName = ViewBag.ArtistNameFilter, AlbumName = ViewBag.AlbumNameFilter, Genre = ViewBag.GenreFilter, ReleaseInit = ViewBag.ReleaseInitFilter, ReleaseEnd = ViewBag.ReleaseEndFilter, NumCopiesInit = ViewBag.NumCopiesInitFilter, NumCopiesEnd = ViewBag.NumCopiesEndFilter }; ViewBag.PrincipalData = _mockAlbumRepository.Filter(filter); } } }
Injected MockRepository.
private readonly IMockAlbumRepository _mockAlbumRepository; public MainViewModel(IMockAlbumRepository mockAlbumRepository) { _mockAlbumRepository = mockAlbumRepository; InitialViewBag(); }
Add
InitialViewBag method
private void InitialViewBag() { ViewBag.PrincipalData = _mockAlbumRepository.GetData(); ViewBag.ArtistNameFilter = string.Empty; ViewBag.AlbumNameFilter = string.Empty; ViewBag.GenreFilter = string.Empty; ViewBag.ReleaseInitFilter = DateTime.Today.AddYears(-50); ViewBag.ReleaseEndFilter = DateTime.Today; ViewBag.NumCopiesInitFilter = 0m; ViewBag.NumCopiesEndFilter = 100000000m; }
Add
FilterCommand
public SimpleRelayCommand FilterCommand => new SimpleRelayCommand(FilterExecuted); private void FilterExecuted() { var filter = new AlbumFilterInfo { ArtistName = ViewBag.ArtistNameFilter, AlbumName = ViewBag.AlbumNameFilter, Genre = ViewBag.GenreFilter, ReleaseInit = ViewBag.ReleaseInitFilter, ReleaseEnd = ViewBag.ReleaseEndFilter, NumCopiesInit = ViewBag.NumCopiesInitFilter, NumCopiesEnd = ViewBag.NumCopiesEndFilter }; ViewBag.PrincipalData = _mockAlbumRepository.Filter(filter); }
Add Code To View Class
In the
View class we have added code for ItemsSorce ListBox property, for Bindings filters controls and the button filter command.
This is a summary of changes.
<ListBox ItemsSource="{Binding ViewBag.PrincipalData}"/> <TextBox Text="{Binding ViewBag.ArtistNameFilter, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/> <TextBox Text="{Binding ViewBag.AlbumNameFilter, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" /> <TextBox Text="{Binding ViewBag.GenreFilter , Mode=TwoWay, UpdateSourceTrigger=LostFocus}" /> <DatePicker SelectedDate="{Binding ViewBag.ReleaseInitFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, StringFormat=dd/MM/yyyy}" /> <DatePicker SelectedDate="{Binding ViewBag.ReleaseEndFilter , Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, StringFormat=dd/MM/yyyy}" /> <TextBox Text="{Binding ViewBag.NumCopiesInitFilter, Mode=TwoWay, UpdateSourceTrigger=LostFocus, StringFormat=n}" /> <TextBox Text="{Binding ViewBag.NumCopiesEndFilter , Mode=TwoWay, UpdateSourceTrigger=LostFocus, StringFormat=n}" /> <Button Command="{Binding FilterCommand}"/>
All process in video.
SetViewBagValue
Exists other
ViewBag instantiation way through SetViewBagValue method. These are its signatures:
public void SetViewBagValue<T>(string propertyName, T value) public void SetViewBagValue(Type type, string propertyName, object value)
Has two versions, generic a non-generic.
The main task is instantiating
ViewBag properties more specifically. In classical ViewBag instantiation the type of ViewBag property is inferred from variable value but in more cases the type inferred isn’t what we wanted it. SetViewBagValue is very practical for ViewBag Nullables types properties builder.
SetViewBagNullValue
SetViewBagNullValue is a ViewModelBase method very similar to SetViewBagValue. Your difference is that SetViewBagNullValue only instance a ViewBag property with nullcode> value. We could think that this code is more comun.
ViewBag.MyProperty = null;
This code throws a new
ArgumentNullException, because Fluent MVVM engine can’t infer the property type.
This is the correct
null initialization
//ViewBag.MyProperty = null; SetViewBagNullValue<string>("MyProperty"); // or SetViewBagNullValue(typeof(string), "MyProperty");
In this case, we have chosen a
string type, we could have chosen any other type that admit null values.
For tests this characteristic let’s add a new control filter. The new control will be a
checkbox and will filter the field HaveIt with this rule.
- Null value .- Show all values
- True value.- Show all true values
- False value.- Show all false values
Since it is not possible to put back to put to null a
ckeckbox value, will add a button to reset current filters.
Add HaveItFilter ViewBag property and ResetCommand to our ViewModel.
private void InitialViewBag() { ViewBag.PrincipalData = _mockAlbumRepository.GetData(); ViewBag.ArtistNameFilter = string.Empty; ViewBag.AlbumNameFilter = string.Empty; ViewBag.GenreFilter = string.Empty; ViewBag.ReleaseInitFilter = DateTime.Today.AddYears(-50); ViewBag.ReleaseEndFilter = DateTime.Today; ViewBag.NumCopiesInitFilter = 0m; ViewBag.NumCopiesEndFilter = 100000000m; SetViewBagNullValue<bool?>("HaveItFilter"); }
FilterCommand
public SimpleRelayCommand ResetCommand => new SimpleRelayCommand(() => InitialViewBag());
Important: We have omited
CanExecute method, because it isn't important for this section. View EaseyRelayCommands for more info.
Add Checkbox filter and reset button to View.
<CheckBox IsChecked="{Binding ViewBag.HaveItFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ... /> <Button Command="{Binding ResetCommand}" ... />
Result.
Checkbox has green background, whit its value is null.
All process in video.
ViewBagPropertyChanged Event
ViewBagPropertyChanged event, is the instrument responsible for reporting ViewBag properties changed. This event allows to makes changes or run actions when our ViewBag properties are modified. In a normal MVVM implementation this actions would be carried in the setters full properties after value assignation.
Example Traditional MVVM.
private string _myProperty; public string MyProperty { get { return _myProperty; } set { _myProperty = value; /// MyActions } }
Example with ViewBag properties.
ViewBagPropertyChanged += (sender, e) =>
{
if(e.PropertyName == "MyProperty")
{
/// My Actions
}
};
For our example, Add ViewBagPropertyChanged event in a InitialBag methood.
private void InitialViewBag() { ViewBag.PrincipalData = _mockAlbumRepository.GetData(); ViewBag.ArtistNameFilter = string.Empty; ViewBag.AlbumNameFilter = string.Empty; ViewBag.GenreFilter = string.Empty; ViewBag.ReleaseInitFilter = DateTime.Today.AddYears(-50); ViewBag.ReleaseEndFilter = DateTime.Today; ViewBag.NumCopiesInitFilter = 0m; ViewBag.NumCopiesEndFilter = 100000000m; SetViewBagNullValue<bool?>("HaveItFilter"); ViewBagPropertyChanged += (sender, e) => { if(e.PropertyName != "PrincipalData") { FilterExecuted(); } }; }
All in video.
Download Examples Code
No hay comentarios :
Publicar un comentario