
System.Windows.Expression: public class System.Windows.Expression: //“This type supports the Windows Presentation Foundation (WPF) infrastructure and is not intended to be used directly from your code”. {Binding HasErrors, Converter={StaticResource InverseBooleanConverter}}{Binding !HasErrors}EventToCommand class for this purpose.UpdateSourceTrigger=PropertyChanged ). On the WinRT platform, this opportunity returned, but the ValidatesOnExceptions and ValidatesOnNotifyDataErrors properties that are responsible for validation disappeared, and the StringFormat property, which is responsible for formatting the result, disappeared.??, ?:, +, -, *, /, %, , ==, !=, <, >, <=, >=, &&(and), ||(or), |, &, !, ~ ), the priority of operations is taken into account in accordance with the C # language standard. Lambda expressions, output of generic types based on values, method call, extension method call, Linq are supported.TargetPath SourcePath, Mode=TwoWay, Validate=trueTargetPath - the path for the Binding of the control.SourcePath - the path for the Binding from a data source or a C # language expression, you can use several paths.Mode, Validate - advanced options for Binding, such as Mode, Fallback, Delay , etc.$self - returns the current control to which the Binding is installed, the {RelativeSource Self} equivalent.$root - returns the current root element for which the Binding is set.$context - returns the current DataContext for Binding, the equivalent of {RelativeSource Self, Path=DataContext} .$args - returns the current parameter EventArgs , can be used only if the TargetPath indicates an event. Text Property, Mode=TwoWay, Validate=True Text Items.First(x => x == Name).Value + Values.Select(x => x.Value).First(x => x == Name), Fallback='empty' Text $string.Format('{0} {1}', Prop1, Prop2), Delay=100 Text $string.Join($Environment.NewLine, $GetErrors()), TargetDelay=1000 Text Property.MyCustomMethod() Text Prop1 ?? Prop2 Text $CustomMethod(Prop1, Prop2, 'string value') Text Prop1 == 'test' ? Prop2 : 'value' EventArgs parameter using the $args keyword. TextChanged EventMethod($args.UndoAction) TextChanged EventMethodMultiParams(Text, $args.UndoAction) INotifyDataErrorInfo interface. Each platform will display an error message. Text Property, Mode=TwoWay, ValidatesOnNotifyDataErrors=True Text Property, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, ValidatesOnExceptions=True Text Property, Mode=TwoWay, Validate=True // ValidatesOnNotifyDataErrors=True, ValidatesOnExceptions=True Enabled = false ) if the command cannot be executed. Click Command, ToggleEnabledState=false // Click Command, ToggleEnabledState=true // $GetErrors() method will return validation errors of the entire form for all properties or errors for specific properties. The method is useful when there is a need to show the user errors on the form. Text $GetErrors(Property).FirstOrDefault() Text $string.Join($Environment.NewLine, $GetErrors()) // , . RelativeSource property for XAML platforms).$Element(ElementName) - searches for an element with the name ElementName.$Relative(Type), $Relative(Type, 1) - searches among the parent control elements with the Type type and (if necessary) taking into account the level of the parent element (second parameter).$self - returns the current element on which the Binding is set. Text $Relative(Window).Title Text $self.ActualWidth Text $Element(NamedSlider).Value DataGridView does not have a SelectedItem property, but we can easily add it using the attached property: var member = AttachedBindingMember.CreateMember<DataGridView, object>("SelectedItem", (info, view) => { var row = view.CurrentRow; if (row == null) return null; return row.DataBoundItem; }, (info, view, item) => { view.ClearSelection(); if (item == null) return; for (int i = 0; i < view.Rows.Count; i++) { if (Equals(view.Rows[i].DataBoundItem, item)) { var row = view.Rows[i]; row.Selected = true; } } }, "CurrentCellChanged"); //CurrentCellChanged - DataGridView, . // BindingServiceProvider.MemberProvider.Register(member); // MyResourceObject i18n BindingServiceProvider.ResourceResolver.AddObject("i18n", new BindingResourceObject(new MyResourceObject())); // Binding Text $i18n.MyResourceString var textBox = new TextBox(); var set = new BindingSet<TextBox, MainViewModel>(textBox); set.Bind(window => window.Text).To(vm => vm.Property).TwoWay(); set.Apply(); INotifyPropertyChanged interface.ICommand interface.Messenger class that allows you to exchange messages between classes.ViewModel regardless of platform.ViewModel , via a constructor with dependencies and parameters.ViewModel and View .ViewModel state management depending on the View life cycle.ViewModel state depending on the platform.ViewModel code for different platforms.IIocContainer interface is used for interaction. Currently, there are implementations for the three DI containers MugenInjection , Autofac , Ninject . The list can be expanded by adding the IIocContainer interface IIocContainer for any other container.ViewModel , for different situations.ViewModelBase - the base class for all ViewModel , contains methods for creating other ViewModel , methods for exchanging messages, methods and properties IsBusy , BusyMessage for managing the state of asynchronous operations.CloseableViewModel - inherited from ViewModelBase , implements the ICloseableViewModel interface, which allows you to manage the process of closing the ViewModel .ValidatableViewModel - ValidatableViewModel from CloseableViewModel , contains methods and properties for validation, implements the INotifyDataErrorInfo interface for notifying Binding about errors.EditableViewModel<T> - inherits from ValidatableViewModel , allows you to edit and validate the data model, monitors the state of the object, and allows you to undo the changes.WorkspaceViewModel, WorkspaceViewModel<TView> - inherits from CloseableViewModel , contains the properties IsSelected and DisplayName - for convenient display of the ViewModel in the interface. Implements the IViewAwareViewModel<TView> interface, which allows access to the View via the IView interface. Implements the INavigableViewModel interface, which allows you to track the navigation process for the ViewModel , OnNavigatedFrom , OnNavigatingFrom , OnNavigatedTo .GridViewModel - inherited from ViewModelBase , allows you to work with collections of various objects.MultiViewModel - inherited from CloseableViewModel , allows you to work with the collections of other ViewModel , well suited for binding to TabControl .ViewModelLocator to create a ViewModel . All ViewModel are created using the DI container, the IViewModelProvider interface is responsible for creating the ViewModel . public class ItemViewModel : ViewModelBase { public ItemViewModel(ISomeService service) { } public void InitializeValue() { } } public class MainViewModel : ViewModelBase { public void CreateViewModelMethod() { // ViewModel var viewModel = GetViewModel<ItemViewModel>(); // , , .. viewModel.InitializeValue(); } } View with ViewModel occurs dynamically. The IViewMappingProvider interface is responsible for IViewMappingProvider , and the default naming convention is used. The following endings are removed for the ViewModel :"ViewModel", "Vm" ,View :"ActivityView", "FragmentView", "WindowView", "PageView", "FormView", "Form", "View", "V", "Activity", "Fragment", "Page", "Window"View corresponds to the ViewModel .MainViewModel, MainVm -> MainActivityView, MainFragmentView, MainWindowView ..View for the ViewModel , you can use the ViewModelAttribute (in this case, the naming convention is ignored): [ViewModel (typeof(MainViewModel))] public partial class MainWindow : Window View and then use it when creating / displaying the ViewModel : [ViewModel (typeof(ItemViewModel), “ViewName”)] public partial class ItemView : Window // ViewModel View // ViewModel View ViewName var viewModel = GetViewModel<ItemViewModel>(parameters: NavigationConstants.ViewName.ToValue("ViewName")); // ViewModel var viewModel = GetViewModel<ItemViewModel>(); // , ViewModel View ViewName viewModel.ShowAsync(NavigationConstants.ViewName.ToValue("ViewName")); ViewModel state. If the ViewModel has a state to save, it must implement the IHasState interface, which has two methods LoadState and SaveState . The system will automatically call these methods depending on the life cycle of the application and the current platform. private static readonly DataConstant<string> StringState = DataConstant.Create(() => StringState, true); public void LoadState(IDataContext state) { // state.AddOrUpdate(StringState, "Constant key"); // state.AddOrUpdate("Test", "String key"); } public void SaveState(IDataContext state) { string data = state.GetData(StringState); var s = state.GetData<string>("Test"); } ViewModel . Navigation in MVVM is one of the most difficult topics, including displaying dialog boxes, adding tabs to TabControl , showing pages for mobile applications, etc. This topic is difficult because on different platforms the same ViewModel can be a dialog box, Page (WinRT, WP, WPF, SL), Activity , Fragment (Android), ViewController (iOS), etc. At the same time, the API for working with the ViewModel should look the same regardless of the platform, since for ViewModel no difference how to display yourself. // var mainWindow = new MainWindow(); // . mainWindow.Init(args); if (!mainWindow.ShowDialog().GetValueOrDefault()) return; // , . // Activity, , . var page2 = new Intent (this, typeof(Page2)); // page2.PutExtra ("arg1", arg) StartActivity (page2); // , , Activity // Android. NavigationService.Navigate(typeof(Page2), arg); MvvmCross : ShowViewModel<DetailViewModel>(new DetailParameters() { Index = 2 }); DetailViewModel must have an Init method that accepts the DetailParameters class: public void Init(DetailParameters parameters) { // use the parameters here } DetailParameters object must be serializable, therefore no complex objects can be transferred. With this approach, it is also very difficult to get the result from the DetailViewModel after the navigation is completed. The approach in MvvmCross is very similar to standard navigation for mobile platforms. You specify the type of the ViewModel , the parameter being serializable and the system displays the View and associates it with the ViewModel . At the same time, it is quite difficult to find out from one ViewModel when another ViewModel was closed. All these restrictions are due to the fact that on mobile devices your application can be completely unloaded from memory, and then restored again, and then there is a problem with saving and restoring state. Basically, this problem is solved by saving the navigation path and serializing the navigation parameters so that they can be restored later.ViewModel closed. Consider an example, you need from Vm1 , show Vm1 and process the result after Vm1 closed, while it does not matter which platform and which display will be on Vm2 : public class Vm2 : ViewModelBase { public void InitFromVm1() { } public object GetResult() { return null; } } public class Vm1 : ViewModelBase { public async void Open() { var vm2 = GetViewModel<Vm2>(); // , . vm2.InitFromVm1(); // IAsyncOperation, // Vm2 IAsyncOperation<bool> asyncOperation = vm2.ShowAsync(Vm2CloseCallback); // asyncOperation.ContinueWith(Vm2CloseCallback); // await await asyncOperation; // Vm2 // var result = vm2.GetResult(); } private void Vm2CloseCallback(IOperationResult<bool> operationResult) { // var result = ((Vm2)operationResult.Source).GetResult(); } private void Vm2CloseCallback(Vm2 vm2, IOperationResult<bool> operationResult) { // var result = vm2.GetResult(); } } Vm2 displayed, and even if your application is unloaded from memory, all registered delegates and state machines will also be saved and then restored. If you want to use async / await on a WinRT or Windows Phone platform, you will need to install a plugin for Fody , this is due to the limitations of reflection for these platforms.Window to any ViewModel , then when you call the ShowAsync method, a dialog box will be shown.ChildWindow class for SL. If you associate ChildWindow with any ViewModel , then when you call the ShowAsync method, a dialog box will be shown.NavigationWindow , for SL - Frame .DataBindingExtension class and the attached property View.Bind . <TextBlock Text="{DataBinding 'Text.ExtensionMethod(Text.Count())'}" /> <TextBlock Text="{DataBinding '$string.IsNullOrEmpty(Text) ? \'String is empty\' : \'String is not empty\''}"/> <TextBlock View.Bind="Text Text.ExtensionMethod(Text.Count())"/> <TextBlock View.Bind="Text $string.IsNullOrEmpty(Text) ? 'String is empty' : 'String is not empty'"/> <Button Click="{DataBinding Path=Command, ToggleEnabledState=False}" /> <Button View.Bind="Click Command, ToggleEnabledState=False" /> <TextBox TextChanged="{DataBinding 'EventMethodMultiParams($self.Text, $args.UndoAction)'}" /> <TextBox View.Bind="TextChanged EventMethodMultiParams($self.Text, $args.UndoAction)" /> Page class. If you match Page with any ViewModel , then when you call the ShowAsync method, a new page will be shown.View.Bind attached property View.Bind . To use it, you must add a namespace: xmlns:markupExtensions="clr-namespace:MugenMvvmToolkit.MarkupExtensions;assembly=MugenMvvmToolkit.WinPhone" xmlns:markupExtensions="using:MugenMvvmToolkit.MarkupExtensions" <TextBlock markupExtensions:View.Bind="Text Text.ExtensionMethod(Text.Count())"/> <TextBlock markupExtensions:View.Bind="Text $string.IsNullOrEmpty(Text) ? 'String is empty' : 'String is not empty'"/> <Button markupExtensions:View.Bind="Click Command, ToggleEnabledState=False" /> <TextBox markupExtensions:View.Bind="TextChanged EventMethodMultiParams($self.Text, $args.UndoAction)" /> DataTemplateSelector for Binding support, analog DataTemplateSelector for Xaml platforms.Form class. If you map a Form to any ViewModel , then when you call the ShowAsync method, a dialog box will be shown.System.Windows.Forms.ErrorProvider class. public class ViewBinder : Binder { public ViewBinder() { } public ViewBinder(IContainer container) : base(container) { } } ViewBinder class should appear ViewBinderBindings property. <Bindings> <addToolStripButton Click="AddNodeCommand" /> <removeToolStripButton Click="RemoveNodeCommand" /> <treeView ItemsSource="Nodes" CollectionViewManager="$treeNodeCollectionViewManager" ItemTemplate="$treeNodeTemplate" SelectedNode.DataContext="SelectedNode, Mode=OneWayToSource" /> <nameTextBox Text="SelectedNode.Name, Mode=TwoWay, Fallback='Nothing selected'" /> <validCheckBox Checked="SelectedNode.IsValid, Mode=TwoWay" /> </Bindings> Activity, for all standard Activitythere is an implementation with the prefix Mvvm, to work you need to inherit not from the standard Activity, but with the prefix Mvvm. If you compare Activitywith any ViewModel, then when you call the method ShowAsync, you will be navigated to a new Activitytype.Fragment, for all standard Fragmentthere is an implementation with the prefix Mvvm, to work you need to inherit not from the standard Fragment, but with the prefix Mvvm. If you compare MvvmDialogFragmentwith any ViewModel, then when the method is called ShowAsync, a dialog box will be displayed.Activity Fragment . Activity Fragment , / ViewModel .back stack fragment .xmlns:pkg="http://schemas.android.com/apk/res-auto" , Binding Bind <ListView android:layout_width="fill_parent" android:layout_height="wrap_content" pkg:ItemTemplate="@layout/_itemlistviewtemplate" pkg:Bind="ItemsSource Items"/> ActionBar , Toolbar , PopupMenu OptionsMenu .DataTemplateSelector Binding, DataTemplateSelector Xaml .TextView.Error . <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" pkg:Bind="Text $Format('Name: {0}, Id: {1}', Name, Id)" /> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" pkg:Bind="Click Command" /> UIViewController , UIViewController Mvvm, UIViewController , Mvvm. UIViewController - ViewModel , ShowAsync , UIViewController .UIViewController .UIViewController . UIViewController , / ViewModel .DataTemplateSelector Binding, DataTemplateSelector Xaml .MonoTouch.Dialog .Page . Page - ViewModel , ShowAsync , .Page .DataBindingExtension attached property View.Bind , Binding. Binding Xaml- xmlns:mugen="clr-namespace:MugenMvvmToolkit.MarkupExtensions;assembly=MugenMvvmToolkit.Xamarin.Forms" <Entry Text="{mugen:DataBinding Name, Mode=TwoWay, Validate=True}" /> <Button Command="{mugen:DataBinding $Relative(ListView).DataContext.ShowCommand}" Text="{mugen:DataBinding Item1}" CommandParameter="{mugen:DataBinding Item2}" /> Source: https://habr.com/ru/post/236745/
All Articles