📜 ⬆️ ⬇️

Windows Phone 8: Create an application. Matrix. Part 3. MVVM

And so, as promised, the third part of the Matrix application for the WP8 platform using the MVVM pattern. For the most impatient, you can immediately download from Github , as well as try it out on your smartphone by downloading from the Windows Phone Store .

Supports screen extensions HD720P (720x1280), WVGA (480x800), WXGA (768x1280). There is a small minus: when using an extension other than 480x800, you need to restart applications after installation, because you did not find how to get the height and width of the Grid element before loading the view model. And now in order.

Windows Phone 8: Create an application. Matrix. Part 1
Windows Phone 8: Create an application. Matrix. Part 2
Windows Phone 8: Create an application. Matrix. Part 3. MVVM
')

An expanded view of the entire application on the WVGA screen (480x800)



Overview of the functionality of the application on the screen WVGA (480x800)

About MVVM


We use the standard template "Panorama with MVVM". But we will correct it so that everything drags from the database. To do this, create a daddy "Models" and "DB". In Models, there will be model definitions, and in DB, for convenience, classes for initial initialization with the values ​​of these models, creating a database, checking it for fullness, and of course the class inheriting DataContext. However, in the class inheriting DataContext, SeDataContext we do not connect one model - Model_Matrixes, since we will not save its values ​​in the database. It is needed only in order to create a grid of the matrix and output falling snakes to it.

Project tree




Daddy "Models"



Briefly about the models: We describe the tables as in the approach “Code first”. Each model is a table in the database. Each property of the model is a column.
In the "set" property: NotifyPropertyChanging and NotifyPropertyChanged are the events that occur before the start of changes in the model and after the changes, respectively. More details can be found on MSDN: INotifyPropertyChanged and INotifyPropertyChanging .

Daddy "DB"




Additional libraries


Since there is no standard color selection, I had to use the Coding4fun library for the ColorPicker element. For the list of languages, I used the Windows Phone Toolkit library, which contains a ListPicker element. Both are easy to install via NuGet.

MainPage.xaml


Now consider the appearance of the application and Binding.
MainPage.xaml
 <phone:PhoneApplicationPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:Controls="clr-namespace:Coding4Fun.Toolkit.Controls;assembly=Coding4Fun.Toolkit.Controls" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" x:Class="SE_Matrix_2d_v_14.MainPage" mc:Ignorable="d" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="False"> <!-- Resources d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}" --> <phone:PhoneApplicationPage.Resources> <!-- SettingsSymbols --> <DataTemplate x:Key="Resources_SettingsSymbols"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="30"/> <RowDefinition Height="70"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="{Binding NameForTranslate}" /> <TextBox x:Name="TextBox_Param_Value" Tag="{Binding ID}" InputScope="Number" Grid.Row="1" Width="300" HorizontalAlignment="Left" Text="{Binding Param_Value, Mode=TwoWay}" TextChanged="Event_TextBox_TextChanged_SettingSymbols" LostFocus="Event_TextBox_LostFocus_SettingsSymbols" /> </Grid> </DataTemplate> <!-- SettingsColor --> <DataTemplate x:Key="SettingsColor"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="25"/> <RowDefinition Height="100"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="{Binding NameForTranslate}" /> <Rectangle Grid.Row="1" Fill="{Binding Value, Mode=TwoWay}" Tag="{Binding ID}" HorizontalAlignment="Left" Height="75" Margin="0,10,0,0" Stroke="Transparent" VerticalAlignment="Top" Width="420" Tap="Event_Rectangle_Tap_ChangeColor"/> </Grid> </DataTemplate> <!-- Matrix --> <DataTemplate x:Key="Matrix"> <TextBlock x:Uid="{Binding Matrix_Name}" Text="{Binding Matrix_Text, Mode=TwoWay}" FontSize="{Binding Matrix_FontSize}" Foreground="{Binding Matrix_Foreground}" /> </DataTemplate> <!-- ListPicker --> <DataTemplate x:Key="ListPickerItemTemplate"> <TextBlock Text="{Binding NameForTranslate}" /> </DataTemplate> <DataTemplate x:Key="ListPickerFullItemTemplate"> <TextBlock Text="{Binding NameForTranslate}" FontSize="{StaticResource PhoneFontSizeExtraLarge}" /> </DataTemplate> </phone:PhoneApplicationPage.Resources> <phone:PhoneApplicationPage.FontFamily> <StaticResource ResourceKey="PhoneFontFamilyNormal"/> </phone:PhoneApplicationPage.FontFamily> <phone:PhoneApplicationPage.FontSize> <StaticResource ResourceKey="PhoneFontSizeNormal"/> </phone:PhoneApplicationPage.FontSize> <phone:PhoneApplicationPage.Foreground> <StaticResource ResourceKey="PhoneForegroundBrush"/> </phone:PhoneApplicationPage.Foreground> <!-- LayoutRoot   ,     --> <Grid x:Name="LayoutRoot" Background="Transparent"> <phone:Panorama> <phone:Panorama.Background> <ImageBrush ImageSource="/SE_Matrix_2d_v_14;component/Assets/PanoramaBackground.png"/> </phone:Panorama.Background> <!--  Panorama --> <phone:PanoramaItem Header="SE "> <phone:LongListSelector Margin="0,0,0,5" ItemsSource="{Binding ItemSourceMatrix}" x:Name="LongListSelector_Matrix" Loaded="Event_LongListSelector_OnLoaded_Matrix" ItemTemplate="{StaticResource Matrix}" GridCellSize="20, 20" LayoutMode="Grid" FontSize="10" Padding="10,0,-5,0" Tap="Event_LongListSelector_Tap_StartMatrix" Background="{Binding Path=ItemSourceMatrixBackground, Mode=TwoWay}" /> </phone:PanoramaItem> <!--  Panorama--> <phone:PanoramaItem Header=" "> <Grid> <Grid.RowDefinitions> <RowDefinition Height="30"/> <RowDefinition Height="60"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <phone:LongListSelector Margin="0,0,-22,0" Grid.Row="2" ItemsSource="{Binding ItemSourceSettingsSymbols}" x:Name="LongListSelector_SettingsSymbols" ItemTemplate="{StaticResource Resources_SettingsSymbols}" /> <toolkit:ListPicker x:Name="sightingTypesPicker" ExpansionMode="FullScreenOnly" FullModeHeader="  " ItemsSource="{Binding ItemSourceLanguage}" FullModeItemTemplate="{StaticResource ListPickerFullItemTemplate}" ItemTemplate="{StaticResource ListPickerItemTemplate}" Grid.Row="1" HorizontalAlignment="Left" SelectedItem="{Binding Path=ItemSourceLanguageSelected, Mode=OneWay}" BorderThickness="0" Height="60" Margin="0" VerticalAlignment="Top" Width="300" SelectionChanged="Event_ListPicker_SelectionChanged" /> <TextBlock Grid.Row="0" Text="  " /> </Grid> </phone:PanoramaItem> <!--   --> <phone:PanoramaItem Header=" "> <Grid VerticalAlignment="Center" HorizontalAlignment="Center"> <Grid.RowDefinitions> <RowDefinition Height="60"/> <RowDefinition Height="60"/> <RowDefinition Height="60"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="SE  1.0" FontSize="{StaticResource PhoneFontSizeLarge}"></TextBlock> <TextBlock Grid.Row="1" Text="se8se@hotmail.com" FontSize="{StaticResource PhoneFontSizeLarge}"></TextBlock> <TextBlock Grid.Row="2" FontSize="{StaticResource PhoneFontSizeLarge}"> SE, 2013</TextBlock> </Grid> </phone:PanoramaItem> <!--  Panorama --> <phone:PanoramaItem Header=" "> <Grid> <Grid.RowDefinitions> <RowDefinition Height="400"/> <RowDefinition Height="20"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Controls:ColorPicker x:Name="ColorPicker" Grid.Row="0" Height="400" VerticalAlignment="Top"/> <phone:LongListSelector Margin="0,0,-22,0" Grid.Row="2" ItemsSource="{Binding ItemSourceSettingsColors}" x:Name="LongListSelector_SettingsColor" ItemTemplate="{StaticResource SettingsColor}" /> </Grid> </phone:PanoramaItem> </phone:Panorama> </Grid> </phone:PhoneApplicationPage> 


This code forms such a picture as at the very beginning of the page. There are no tricks, standard XAML, but if you have any questions, ask. I'll be glad to help.

Daddy "ViewModels"


Got to the heart of our application. That for which everything was started. So, just two classes.



Helpers daddy



MainPage.xaml.cs


Nothing new. Basically, only the event of clicking or loss of focus.
MainPage.xaml.cs
 using System; using System.Net; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Navigation; using Microsoft.Phone.Controls; using Microsoft.Phone.Shell; using SE_Matrix_2d_v_14.Models; using System.Windows.Shapes; using System.Diagnostics; using System.Reflection; using System.Windows.Media; namespace SE_Matrix_2d_v_14 { public partial class MainPage : PhoneApplicationPage { //  public MainPage() { InitializeComponent(); //       listbox   this.DataContext = App.ViewModel; } //     ViewModel protected override void OnNavigatedTo(NavigationEventArgs e) { if (!App.ViewModel.IsDataLoaded) { App.ViewModel.LoadData(); } App.ViewModel.SaveChangesToDB(); } private bool _updateSettings = false; public bool UpdateSettings { get { return _updateSettings; } set { _updateSettings = value; } } /// <summary> ///          0,     true,  ///             /// </summary> private void Event_TextBox_TextChanged_SettingSymbols(object sender, TextChangedEventArgs e) { TextBox paramToUpdate = sender as TextBox; if (paramToUpdate.Text.Length > 0) { UpdateSettings = true; } } /// <summary> ///  UpdateSettings == true,         ,   /// </summary> private void Event_TextBox_LostFocus_SettingsSymbols(object sender, RoutedEventArgs e) { TextBox paramToUpdate = sender as TextBox; if (UpdateSettings == true) { UpdateSettings = false; Model_SettingsSymbols updateInTable = new Model_SettingsSymbols { ID = Convert.ToInt32(paramToUpdate.Tag), Param_Value = Convert.ToInt32(paramToUpdate.Text) }; App.ViewModel.UpdateSettingsSymbolsByID(updateInTable); } } /// <summary> ///      ,    /// </summary> private void Event_LongListSelector_OnLoaded_Matrix(object sender, RoutedEventArgs e) { LongListSelector paramToUpdate = sender as LongListSelector; Model_SettingsSymbols updateHeightInTable = new Model_SettingsSymbols { Param_Name = "Param_WindowHeight", Param_Value = Convert.ToInt32(paramToUpdate.ActualHeight) }; App.ViewModel.UpdateSettingsSymbolsByName(updateHeightInTable); Model_SettingsSymbols updateWigthInTable = new Model_SettingsSymbols { Param_Name = "Param_WindowWidth", Param_Value = Convert.ToInt32(paramToUpdate.ActualWidth) }; App.ViewModel.UpdateSettingsSymbolsByName(updateWigthInTable); } /// <summary> ///    ,    -        . /// </summary> private async void Event_LongListSelector_Tap_StartMatrix(object sender, System.Windows.Input.GestureEventArgs e) { App.ViewModel.Start(); } /// <summary> ///         -         /// </summary> private void Event_Rectangle_Tap_ChangeColor(object sender, System.Windows.Input.GestureEventArgs e) { Rectangle paramToUpdate = sender as Rectangle; Model_Colors updateInTable = new Model_Colors { ID = Convert.ToInt32(paramToUpdate.Tag), Value = ColorPicker.Color.ToString() }; App.ViewModel.UpdateSettingsColorByID(updateInTable); } /// <summary> ///          /// </summary> private void Event_ListPicker_SelectionChanged(object sender, SelectionChangedEventArgs e) { Module_Languages selectedItem = ((sender as ListPicker).SelectedItem as Module_Languages); Module_Languages updateInTable = new Module_Languages { ID = selectedItem.ID }; App.ViewModel.UpdateSettingsColorByID(updateInTable); } } } 


findings


The amount of code has increased, but increased readability and extensibility. MVVM is much more convenient in this case. However, the performance of the application (estimated at the maximum number of snakes in the matrix, at which there is no slowdown) has slightly decreased.

In the following articles, we will fix some minor bugs, add an increase in the matrix to the full screen when you double-click, we will start translating the application for other platforms using Xamarin: Android and IOS.

P.S.


If you are minus one, then at least indicate why. Interesting!

Source: https://habr.com/ru/post/201240/


All Articles