Дополнительные материалы к занятию можно скачать здесь.
Вложенные папки: LocalDataBaseSample
| Ссылки: | http://msdn.microsoft.com/en-us/library/ff431744(v=vs.92).aspx |
| http://silverlight.codeplex.com/releases/view/60291 | |
| http://create.msdn.com/en-us/home/getting_started |
В новой версии операционной системы Windows Phone OS 7.1 появилась возможность хранить информацию в реляционных базах данных, которая выступает в роли изолированного контейнера приложения. Для работы с базами данных приложения Windows Phone используют операторы LINQ to SQL. С помощью LINQ to SQL можно задать схему базы данных, осуществлять извлечение данных, а также сохранять изменения в файле базы данных.
На рис 33.1 показана связь между приложением и изолированным хранилищем. Для связи с хранилищем в приложении создается объект DataContext.
(рис 33.1) Связь между приложением и изолированным хранилищем
Перед началом работы с локальной базой данных нужно учесть следующее.
| LINQ to SQL используется в качестве ORM engine |
| Файл базы данных хранится в изолированном хранилище |
| Для извлечения данных используется LINQ, T-SQL не подходит |
| Локальная база данных в Windows Phone Mango не увеличивает объем приложения, так как является частью универсальной исполняющей машины |
| К проекту нужно добавить ссылку на сборку System.Data.Linq |
При написании строки подключения используется специфический формат, подобный:
"Data Source='isostore:/DIRECTORY/FILE.sdf'";
|
В данной работе мы создадим базу данных, в главной таблице которой будут храниться классы позвоночных животных, а в подчиненной таблице - виды. За основу мы взяли пример, описанный на сайте Microsoft (http://msdn.microsoft.com/en-us/library/ff431744(v=vs.92).aspx), и немного его переработали.
Для работы нам потребуется новая сборка . После инсталляции файла SilverlightforWindowsPhoneToolkit-Feb2011.msi можно узнать местонахождения файла Microsoft.Phone.Controls.Toolkit.dll следующим образом. Выполните следующую последовательность действий: Пуск -> Все программы -> Microsoft Silverlight for Windows Phone Toolkit -> Binaries. Эта сборка содержит следующие полезные компоненты:
| AutoCompleteBox |
| ContextMenu |
| DatePicker |
| GestureService/GestureListener |
| ListPicker |
| LongListSelector |
| Page Transitions |
| PerformanceProgressBar |
| TiltEffect |
| TimePicker |
| ToggleSwitch |
| WrapPanel |
Нам потребуется элемент управления .
В Visual Studio создаем новое приложение Silverlight for Windows Phone. Назовем его LocalDataBaseSample. В пункте Target Windows Phone Version выберите Windows Phone 7.1.
Скопируйте файл Microsoft.Phone.Controls.Toolkit.dll, описанный выше в папку вашего проекта, например, в папку …\LocalDatabaseSample\LocalDatabaseSample\Bin\Debug. Подключите сборку к проекту, выполнив следующие действия: Solution Explorer -> References -> Add Reference -> Path… -> Microsoft.Phone.Controls.Toolkit.dll.
Далее, нам потребуется подключить к проекту ссылку на сборку System.Data.Linq: Solution Explorer -> References -> Add Reference -> .Net -> System.Data.Linq -> OK.
Для нашего приложения необходимы четыре иконки: appbar.add.rest.png, appbar.cancel.rest.png, appbar.check.rest.png, appbar.delete.rest.png, расположенные по адресу:
C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Icons\dark (64-х разрядные операционные системы)
C:\Program Files\Microsoft SDKs\Windows Phone\v7.1\Icons\dark (32-х разрядные операционные системы)
Создайте папку Images (Solution Explorer -> Add -> Create Folder -> Images), скопируйте туда иконки и добавьте к проекту (Solution Explorer -> Images -> Add -> Existent Item).
Откройте файл MainPage.xaml и заполните его следующим содержимым:
<phone:PhoneApplicationPage
x:Class="LocalDatabaseSample.MainPage"
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: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"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="696"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True"
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls">
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="AnimalListBoxItemTemplate">
<Grid HorizontalAlignment="Stretch" Width="420">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<CheckBox
IsChecked="{Binding IsComplete, Mode=TwoWay}"
Grid.Column="0" VerticalAlignment="Top"/>
<TextBlock
Text="{Binding ItemName}"
FontSize="{StaticResource PhoneFontSizeLarge}"
Grid.Column="1" Grid.ColumnSpan="2"
VerticalAlignment="Top" Margin="-36, 12, 0, 0"/>
<Button
Grid.Column="3"
x:Name="deleteTaskButton"
BorderThickness="0"
Margin="0, -18, 0, 0"
Click="deleteTaskButton_Click">
<Image
Source="/Images/appbar.delete.rest.png"
Height="75"
Width="75"/>
</Button>
</Grid>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed.-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title.-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock
x:Name="ApplicationTitle"
Text="Образец локальной базы данных: зоология"
Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<!--ContentPanel - place additional content here.-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<controls:Pivot Margin="0, -36, 0, 0">
<controls:PivotItem Header="Все">
<ListBox
x:Name="allAnimalItemsListBox"
ItemsSource="{Binding AllAnimalItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource AnimalListBoxItemTemplate}" />
</controls:PivotItem>
<controls:PivotItem Header="Птицы">
<ListBox
x:Name="BirdsAnimalItemsListBox"
ItemsSource="{Binding BirdsAnimalItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource AnimalListBoxItemTemplate}" />
</controls:PivotItem>
<controls:PivotItem Header="Пресмыкающиеся">
<ListBox
x:Name="ReptilesAnimalItemsListBox"
ItemsSource="{Binding ReptilesAnimalItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource AnimalListBoxItemTemplate}" />
</controls:PivotItem>
<controls:PivotItem Header="Рыбы">
<ListBox
x:Name="FishesAnimalItemsListBox"
ItemsSource="{Binding FishesAnimalItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource AnimalListBoxItemTemplate}" />
</controls:PivotItem>
</controls:Pivot>
</Grid>
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton
IconUri="/Images/appbar.add.rest.png"
Text="add"
x:Name="newTaskAppBarButton"
Click="newTaskAppBarButton_Click"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
</phone:PhoneApplicationPage>
Откройте файл MainPage.xaml.cs и введите следующий код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
// Directive for the ViewModel.
using LocalDatabaseSample.Model;
namespace LocalDatabaseSample
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// Set the page DataContext property to the ViewModel.
this.DataContext = App.ViewModel;
}
private void newTaskAppBarButton_Click(object sender, EventArgs e)
{
NavigationService.Navigate(new Uri("/NewTaskPage.xaml", UriKind.Relative));
}
private void deleteTaskButton_Click(object sender, RoutedEventArgs e)
{
// Cast the parameter as a button.
var button = sender as Button;
if (button != null)
{
// Get a handle for the Animal item bound to the button.
AnimalItem AnimalForDelete = button.DataContext as AnimalItem;
App.ViewModel.DeleteAnimalItem(AnimalForDelete);
}
// Put the focus back to the main page.
this.Focus();
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
// Save changes to the database.
App.ViewModel.SaveChangesToDB();
}
}
}
Добавьте файл NewTaskPage.xaml в портретной ориентации:
Содержимое файла NewTaskPage.xaml:
<phone:PhoneApplicationPage
x:Class="LocalDatabaseSample.NewTaskPage"
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: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"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="696" d:DesignWidth="480"
shell:SystemTray.IsVisible="True"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit">
<!--LayoutRoot is the root grid where all page content is placed.-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title.-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock
x:Name="ApplicationTitle"
Text="Образец локальной базы данных: Зоология"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock
x:Name="PageTitle"
Text="Добавить"
Margin="9,-7,0,0"
Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here.-->
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Вид"/>
<TextBox x:Name="newTaskNameTextBox"/>
<TextBlock Text="Класс"/>
<toolkit:ListPicker
x:Name="categoriesListPicker"
ItemsSource="{Binding CategoriesList}"
DisplayMemberPath="Name">
</toolkit:ListPicker>
</StackPanel>
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton
x:Name="appBarOkButton"
IconUri="/Images/appbar.check.rest.png"
Text="ok"
Click="appBarOkButton_Click"/>
<shell:ApplicationBarIconButton
x:Name="appBarCancelButton"
IconUri="/Images/appbar.cancel.rest.png"
Text="cancel"
Click="appBarCancelButton_Click"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
</phone:PhoneApplicationPage>
Перейдите к файлу NewTaskPage.xaml.cs и введите следующий код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
// Directive for the data model.
using LocalDatabaseSample.Model;
namespace LocalDatabaseSample
{
public partial class NewTaskPage : PhoneApplicationPage
{
public NewTaskPage()
{
InitializeComponent();
// Set the page DataContext property to the ViewModel.
this.DataContext = App.ViewModel;
}
private void appBarOkButton_Click(object sender, EventArgs e)
{
// Confirm there is some text in the text box.
if (newTaskNameTextBox.Text.Length > 0)
{
// Create a new Animal item.
AnimalItem newAnimalItem = new AnimalItem
{
ItemName = newTaskNameTextBox.Text,
Category = (AnimalCategory)categoriesListPicker.SelectedItem
};
// Add the item to the ViewModel.
App.ViewModel.AddAnimalItem(newAnimalItem);
// Return to the main page.
if (NavigationService.CanGoBack)
{
NavigationService.GoBack();
}
}
}
private void appBarCancelButton_Click(object sender, EventArgs e)
{
// Return to the main page.
if (NavigationService.CanGoBack)
{
NavigationService.GoBack();
}
}
}
}
Откройте файл App.xaml.cs и введите следующий код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
// Directives
using LocalDatabaseSample.Model;
using LocalDatabaseSample.ViewModel;
namespace LocalDatabaseSample
{
public partial class App : Application
{
/// <summary>
/// Provides easy access to the root frame of the Phone Application.
/// </summary>
/// <returns>The root frame of the Phone Application.</returns>
public PhoneApplicationFrame RootFrame { get; private set; }
// The static ViewModel, to be used across the application.
private static AnimalViewModel viewModel;
public static AnimalViewModel ViewModel
{
get { return viewModel; }
}
/// <summary>
/// Constructor for the Application object.
/// </summary>
public App()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
// Standard Silverlight initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode,
// which shows areas of a page that are handed off to GPU with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
// Disable the application idle detection by setting the UserIdleDetectionMode property of the
// application's PhoneApplicationService object to Disabled.
// Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
// and consume battery power when the user is not using the phone.
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
// Specify the local database connection string.
string DBConnectionString = "Data Source=isostore:/Animal.sdf";
// Create the database if it does not exist.
using (AnimalDataContext db = new AnimalDataContext(DBConnectionString))
{
if (db.DatabaseExists() == false)
{
// Create the local database.
db.CreateDatabase();
// Prepopulate the categories.
db.Categories.InsertOnSubmit(new AnimalCategory { Name = "Птицы" });
db.Categories.InsertOnSubmit(new AnimalCategory { Name = "Пресмыкающиеся" });
db.Categories.InsertOnSubmit(new AnimalCategory { Name = "Рыбы" });
// Save categories to the database.
db.SubmitChanges();
}
}
// Create the ViewModel object.
viewModel = new AnimalViewModel(DBConnectionString);
// Query the local database and load observable collections.
viewModel.LoadCollectionsFromDatabase();
}
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
}
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
}
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
}
// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
}
// Code to execute if a navigation fails
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// A navigation has failed; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
#region Phone application initialization
// Avoid double-initialization
private bool phoneApplicationInitialized = false;
// Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
// Do not add any additional code to this method
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
#endregion
}
}
Создайте папку Model и разместите в ней файл кода AnimalDataContext.cs со следующим содержимым:
using System;
using System.ComponentModel;
using System.Data.Linq;
using System.Data.Linq.Mapping;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
namespace LocalDatabaseSample.Model
{
public class AnimalDataContext : DataContext
{
// Pass the connection string to the base class.
public AnimalDataContext(string connectionString)
: base(connectionString)
{ }
// Specify a table for the Animal items.
public Table<AnimalItem> Items;
// Specify a table for the categories.
public Table<AnimalCategory> Categories;
}
[Table]
public class AnimalItem : INotifyPropertyChanged, INotifyPropertyChanging
{
// Define ID: private field, public property, and database column.
private int _AnimalItemId;
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity",
CanBeNull = false, AutoSync = AutoSync.OnInsert)]
public int AnimalItemId
{
get { return _AnimalItemId; }
set
{
if (_AnimalItemId != value)
{
NotifyPropertyChanging("AnimalItemId");
_AnimalItemId = value;
NotifyPropertyChanged("AnimalItemId");
}
}
}
// Define item name: private field, public property, and database column.
private string _itemName;
[Column]
public string ItemName
{
get { return _itemName; }
set
{
if (_itemName != value)
{
NotifyPropertyChanging("ItemName");
_itemName = value;
NotifyPropertyChanged("ItemName");
}
}
}
// Define completion value: private field, public property, and database column.
private bool _isComplete;
[Column]
public bool IsComplete
{
get { return _isComplete; }
set
{
if (_isComplete != value)
{
NotifyPropertyChanging("IsComplete");
_isComplete = value;
NotifyPropertyChanged("IsComplete");
}
}
}
// Internal column for the associated AnimalCategory ID value
[Column]
internal int _categoryId;
// Entity reference, to identify the AnimalCategory "storage" table
private EntityRef<AnimalCategory> _category;
// Association, to describe the relationship between this key and that "storage" table
[Association(Storage = "_category", ThisKey = "_categoryId",
OtherKey = "Id", IsForeignKey = true)]
public AnimalCategory Category
{
get { return _category.Entity; }
set
{
NotifyPropertyChanging("Category");
_category.Entity = value;
if (value != null)
{
_categoryId = value.Id;
}
NotifyPropertyChanging("Category");
}
}
// Version column aids update performance.
[Column(IsVersion = true)]
private Binary _version;
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Used to notify that a property changed
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region INotifyPropertyChanging Members
public event PropertyChangingEventHandler PropertyChanging;
// Used to notify that a property is about to change
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
#endregion
}
[Table]
public class AnimalCategory : INotifyPropertyChanged, INotifyPropertyChanging
{
// Define ID: private field, public property, and database column.
private int _id;
[Column(DbType = "INT NOT NULL IDENTITY", IsDbGenerated = true, IsPrimaryKey = true)]
public int Id
{
get { return _id; }
set
{
NotifyPropertyChanging("Id");
_id = value;
NotifyPropertyChanged("Id");
}
}
// Define category name: private field, public property, and database column.
private string _name;
[Column]
public string Name
{
get { return _name; }
set
{
NotifyPropertyChanging("Name");
_name = value;
NotifyPropertyChanged("Name");
}
}
// Define the entity set for the collection side of the relationship.
private EntitySet<AnimalItem> _Animals;
[Association(Storage = "_Animals", OtherKey = "_categoryId", ThisKey = "Id")]
public EntitySet<AnimalItem> Animals
{
get { return this._Animals; }
set { this._Animals.Assign(value); }
}
// Assign handlers for the add and remove operations, respectively.
public AnimalCategory()
{
_Animals = new EntitySet<AnimalItem>(
new Action<AnimalItem>(this.attach_Animal),
new Action<AnimalItem>(this.detach_Animal)
);
}
// Called during an add operation
private void attach_Animal(AnimalItem Animal)
{
NotifyPropertyChanging("AnimalItem");
Animal.Category = this;
}
// Called during a remove operation
private void detach_Animal(AnimalItem Animal)
{
NotifyPropertyChanging("AnimalItem");
Animal.Category = null;
}
// Version column aids update performance.
[Column(IsVersion = true)]
private Binary _version;
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Used to notify that a property changed
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region INotifyPropertyChanging Members
public event PropertyChangingEventHandler PropertyChanging;
// Used to notify that a property is about to change
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
#endregion
}
}
Создайте папку ViewModel и разместите в ней файл AnimalViewModel.cs со следующим содержимым:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
// Directive for the data model.
using LocalDatabaseSample.Model;
namespace LocalDatabaseSample.ViewModel
{
public class AnimalViewModel : INotifyPropertyChanged
{
// LINQ to SQL data context for the local database.
private AnimalDataContext AnimalDB;
// Class constructor, create the data context object.
public AnimalViewModel(string AnimalDBConnectionString)
{
AnimalDB = new AnimalDataContext(AnimalDBConnectionString);
}
// All to-do items.
private ObservableCollection<AnimalItem> _allAnimalItems;
public ObservableCollection<AnimalItem> AllAnimalItems
{
get { return _allAnimalItems; }
set
{
_allAnimalItems = value;
NotifyPropertyChanged("AllAnimalItems");
}
}
// Animal items associated with the Birds category.
private ObservableCollection<AnimalItem> _BirdsAnimalItems;
public ObservableCollection<AnimalItem> BirdsAnimalItems
{
get { return _BirdsAnimalItems; }
set
{
_BirdsAnimalItems = value;
NotifyPropertyChanged("BirdsAnimalItems");
}
}
// Animal items associated with the Reptiles category.
private ObservableCollection<AnimalItem> _ReptilesAnimalItems;
public ObservableCollection<AnimalItem> ReptilesAnimalItems
{
get { return _ReptilesAnimalItems; }
set
{
_ReptilesAnimalItems = value;
NotifyPropertyChanged("ReptilesAnimalItems");
}
}
// Animal items associated with the Fishes category.
private ObservableCollection<AnimalItem> _FishesAnimalItems;
public ObservableCollection<AnimalItem> FishesAnimalItems
{
get { return _FishesAnimalItems; }
set
{
_FishesAnimalItems = value;
NotifyPropertyChanged("FishesAnimalItems");
}
}
// A list of all categories, used by the add task page.
private List<AnimalCategory> _categoriesList;
public List<AnimalCategory> CategoriesList
{
get { return _categoriesList; }
set
{
_categoriesList = value;
NotifyPropertyChanged("CategoriesList");
}
}
// Query database and load the collections and list used by the pivot pages.
public void LoadCollectionsFromDatabase()
{
// Specify the query for all to-do items in the database.
var AnimalItemsInDB = from AnimalItem Animal in AnimalDB.Items
select Animal;
// Query the database and load all to-do items.
AllAnimalItems = new ObservableCollection<AnimalItem>(AnimalItemsInDB);
// Specify the query for all categories in the database.
var AnimalCategoriesInDB = from AnimalCategory category in AnimalDB.Categories
select category;
// Query the database and load all associated items to their respective collections.
foreach (AnimalCategory category in AnimalCategoriesInDB)
{
switch (category.Name)
{
case "Птицы":
BirdsAnimalItems = new ObservableCollection<AnimalItem>(category.Animals);
break;
case "Пресмыкающиеся":
ReptilesAnimalItems = new ObservableCollection<AnimalItem>(category.Animals);
break;
case "Рыбы":
FishesAnimalItems = new ObservableCollection<AnimalItem>(category.Animals);
break;
default:
break;
}
}
// Load a list of all categories.
CategoriesList = AnimalDB.Categories.ToList();
}
// Add an Animal item to the database and collections.
public void AddAnimalItem(AnimalItem newAnimalItem)
{
// Add an Animal item to the data context.
AnimalDB.Items.InsertOnSubmit(newAnimalItem);
// Save changes to the database.
AnimalDB.SubmitChanges();
// Add an Animal item to the "all" observable collection.
AllAnimalItems.Add(newAnimalItem);
// Add an Animal item to the appropriate filtered collection.
switch (newAnimalItem.Category.Name)
{
case "Птицы":
BirdsAnimalItems.Add(newAnimalItem);
break;
case "Пресмыкающиеся":
ReptilesAnimalItems.Add(newAnimalItem);
break;
case "Рыбы":
FishesAnimalItems.Add(newAnimalItem);
break;
default:
break;
}
}
// Remove an Animal task item from the database and collections.
public void DeleteAnimalItem(AnimalItem AnimalForDelete)
{
// Remove the Animal item from the "all" observable collection.
AllAnimalItems.Remove(AnimalForDelete);
// Remove the Animal item from the data context.
AnimalDB.Items.DeleteOnSubmit(AnimalForDelete);
// Remove the Animal item from the appropriate category.
switch (AnimalForDelete.Category.Name)
{
case "Птицы":
BirdsAnimalItems.Remove(AnimalForDelete);
break;
case "Пресмыкающиеся":
ReptilesAnimalItems.Remove(AnimalForDelete);
break;
case "Рыбы":
FishesAnimalItems.Remove(AnimalForDelete);
break;
default:
break;
}
// Save changes to the database.
AnimalDB.SubmitChanges();
}
// Write changes in the data context to the database.
public void SaveChangesToDB()
{
AnimalDB.SubmitChanges();
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Used to notify Silverlight that a property has changed.
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
Запустите проект, нажав клавишу F5. Нажмите на кнопку Start, затем выберите пункт SETTINGS:
Выберите пункт Region + Language, В разделе Display language выберите русский язык:
Сохраните настройки.
Вернитесь в приложение LocalDataBaseSample. Поработайте с базой данных.
Дополнительные материалы к занятию можно скачать здесь.
Вложенные папки: LocalDataBaseSample
| Ссылки: | http://msdn.microsoft.com/en-us/library/ff431744(v=vs.92).aspx |
| http://silverlight.codeplex.com/releases/view/60291 | |
| http://create.msdn.com/en-us/home/getting_started |
В новой версии операционной системы Windows Phone OS 7.1 появилась возможность хранить информацию в реляционных базах данных, которая выступает в роли изолированного контейнера приложения. Для работы с базами данных приложения Windows Phone используют операторы LINQ to SQL. С помощью LINQ to SQL можно задать схему базы данных, осуществлять извлечение данных, а также сохранять изменения в файле базы данных.
На рис 33.1 показана связь между приложением и изолированным хранилищем. Для связи с хранилищем в приложении создается объект DataContext.
(рис 33.1) Связь между приложением и изолированным хранилищем
Перед началом работы с локальной базой данных нужно учесть следующее.
| LINQ to SQL используется в качестве ORM engine |
| Файл базы данных хранится в изолированном хранилище |
| Для извлечения данных используется LINQ, T-SQL не подходит |
| Локальная база данных в Windows Phone Mango не увеличивает объем приложения, так как является частью универсальной исполняющей машины |
| К проекту нужно добавить ссылку на сборку System.Data.Linq |
При написании строки подключения используется специфический формат, подобный:
"Data Source='isostore:/DIRECTORY/FILE.sdf'";
|
В данной работе мы создадим базу данных, в главной таблице которой будут храниться классы позвоночных животных, а в подчиненной таблице - виды. За основу мы взяли пример, описанный на сайте Microsoft (http://msdn.microsoft.com/en-us/library/ff431744(v=vs.92).aspx), и немного его переработали.
Для работы нам потребуется новая сборка . После инсталляции файла SilverlightforWindowsPhoneToolkit-Feb2011.msi можно узнать местонахождения файла Microsoft.Phone.Controls.Toolkit.dll следующим образом. Выполните следующую последовательность действий: Пуск -> Все программы -> Microsoft Silverlight for Windows Phone Toolkit -> Binaries. Эта сборка содержит следующие полезные компоненты:
| AutoCompleteBox |
| ContextMenu |
| DatePicker |
| GestureService/GestureListener |
| ListPicker |
| LongListSelector |
| Page Transitions |
| PerformanceProgressBar |
| TiltEffect |
| TimePicker |
| ToggleSwitch |
| WrapPanel |
Нам потребуется элемент управления .
В Visual Studio создаем новое приложение Silverlight for Windows Phone. Назовем его LocalDataBaseSample. В пункте Target Windows Phone Version выберите Windows Phone 7.1.
Скопируйте файл Microsoft.Phone.Controls.Toolkit.dll, описанный выше в папку вашего проекта, например, в папку …\LocalDatabaseSample\LocalDatabaseSample\Bin\Debug. Подключите сборку к проекту, выполнив следующие действия: Solution Explorer -> References -> Add Reference -> Path… -> Microsoft.Phone.Controls.Toolkit.dll.
Далее, нам потребуется подключить к проекту ссылку на сборку System.Data.Linq: Solution Explorer -> References -> Add Reference -> .Net -> System.Data.Linq -> OK.
Для нашего приложения необходимы четыре иконки: appbar.add.rest.png, appbar.cancel.rest.png, appbar.check.rest.png, appbar.delete.rest.png, расположенные по адресу:
C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Icons\dark (64-х разрядные операционные системы)
C:\Program Files\Microsoft SDKs\Windows Phone\v7.1\Icons\dark (32-х разрядные операционные системы)
Создайте папку Images (Solution Explorer -> Add -> Create Folder -> Images), скопируйте туда иконки и добавьте к проекту (Solution Explorer -> Images -> Add -> Existent Item).
Откройте файл MainPage.xaml и заполните его следующим содержимым:
<phone:PhoneApplicationPage
x:Class="LocalDatabaseSample.MainPage"
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: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"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="696"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True"
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls">
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="AnimalListBoxItemTemplate">
<Grid HorizontalAlignment="Stretch" Width="420">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<CheckBox
IsChecked="{Binding IsComplete, Mode=TwoWay}"
Grid.Column="0" VerticalAlignment="Top"/>
<TextBlock
Text="{Binding ItemName}"
FontSize="{StaticResource PhoneFontSizeLarge}"
Grid.Column="1" Grid.ColumnSpan="2"
VerticalAlignment="Top" Margin="-36, 12, 0, 0"/>
<Button
Grid.Column="3"
x:Name="deleteTaskButton"
BorderThickness="0"
Margin="0, -18, 0, 0"
Click="deleteTaskButton_Click">
<Image
Source="/Images/appbar.delete.rest.png"
Height="75"
Width="75"/>
</Button>
</Grid>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed.-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title.-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock
x:Name="ApplicationTitle"
Text="Образец локальной базы данных: зоология"
Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<!--ContentPanel - place additional content here.-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<controls:Pivot Margin="0, -36, 0, 0">
<controls:PivotItem Header="Все">
<ListBox
x:Name="allAnimalItemsListBox"
ItemsSource="{Binding AllAnimalItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource AnimalListBoxItemTemplate}" />
</controls:PivotItem>
<controls:PivotItem Header="Птицы">
<ListBox
x:Name="BirdsAnimalItemsListBox"
ItemsSource="{Binding BirdsAnimalItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource AnimalListBoxItemTemplate}" />
</controls:PivotItem>
<controls:PivotItem Header="Пресмыкающиеся">
<ListBox
x:Name="ReptilesAnimalItemsListBox"
ItemsSource="{Binding ReptilesAnimalItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource AnimalListBoxItemTemplate}" />
</controls:PivotItem>
<controls:PivotItem Header="Рыбы">
<ListBox
x:Name="FishesAnimalItemsListBox"
ItemsSource="{Binding FishesAnimalItems}"
Margin="12, 0, 12, 0" Width="440"
ItemTemplate="{StaticResource AnimalListBoxItemTemplate}" />
</controls:PivotItem>
</controls:Pivot>
</Grid>
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton
IconUri="/Images/appbar.add.rest.png"
Text="add"
x:Name="newTaskAppBarButton"
Click="newTaskAppBarButton_Click"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
</phone:PhoneApplicationPage>
Откройте файл MainPage.xaml.cs и введите следующий код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
// Directive for the ViewModel.
using LocalDatabaseSample.Model;
namespace LocalDatabaseSample
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// Set the page DataContext property to the ViewModel.
this.DataContext = App.ViewModel;
}
private void newTaskAppBarButton_Click(object sender, EventArgs e)
{
NavigationService.Navigate(new Uri("/NewTaskPage.xaml", UriKind.Relative));
}
private void deleteTaskButton_Click(object sender, RoutedEventArgs e)
{
// Cast the parameter as a button.
var button = sender as Button;
if (button != null)
{
// Get a handle for the Animal item bound to the button.
AnimalItem AnimalForDelete = button.DataContext as AnimalItem;
App.ViewModel.DeleteAnimalItem(AnimalForDelete);
}
// Put the focus back to the main page.
this.Focus();
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
// Save changes to the database.
App.ViewModel.SaveChangesToDB();
}
}
}
Добавьте файл NewTaskPage.xaml в портретной ориентации:
Содержимое файла NewTaskPage.xaml:
<phone:PhoneApplicationPage
x:Class="LocalDatabaseSample.NewTaskPage"
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: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"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="696" d:DesignWidth="480"
shell:SystemTray.IsVisible="True"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit">
<!--LayoutRoot is the root grid where all page content is placed.-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title.-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock
x:Name="ApplicationTitle"
Text="Образец локальной базы данных: Зоология"
Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock
x:Name="PageTitle"
Text="Добавить"
Margin="9,-7,0,0"
Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here.-->
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="Вид"/>
<TextBox x:Name="newTaskNameTextBox"/>
<TextBlock Text="Класс"/>
<toolkit:ListPicker
x:Name="categoriesListPicker"
ItemsSource="{Binding CategoriesList}"
DisplayMemberPath="Name">
</toolkit:ListPicker>
</StackPanel>
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton
x:Name="appBarOkButton"
IconUri="/Images/appbar.check.rest.png"
Text="ok"
Click="appBarOkButton_Click"/>
<shell:ApplicationBarIconButton
x:Name="appBarCancelButton"
IconUri="/Images/appbar.cancel.rest.png"
Text="cancel"
Click="appBarCancelButton_Click"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
</phone:PhoneApplicationPage>
Перейдите к файлу NewTaskPage.xaml.cs и введите следующий код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
// Directive for the data model.
using LocalDatabaseSample.Model;
namespace LocalDatabaseSample
{
public partial class NewTaskPage : PhoneApplicationPage
{
public NewTaskPage()
{
InitializeComponent();
// Set the page DataContext property to the ViewModel.
this.DataContext = App.ViewModel;
}
private void appBarOkButton_Click(object sender, EventArgs e)
{
// Confirm there is some text in the text box.
if (newTaskNameTextBox.Text.Length > 0)
{
// Create a new Animal item.
AnimalItem newAnimalItem = new AnimalItem
{
ItemName = newTaskNameTextBox.Text,
Category = (AnimalCategory)categoriesListPicker.SelectedItem
};
// Add the item to the ViewModel.
App.ViewModel.AddAnimalItem(newAnimalItem);
// Return to the main page.
if (NavigationService.CanGoBack)
{
NavigationService.GoBack();
}
}
}
private void appBarCancelButton_Click(object sender, EventArgs e)
{
// Return to the main page.
if (NavigationService.CanGoBack)
{
NavigationService.GoBack();
}
}
}
}
Откройте файл App.xaml.cs и введите следующий код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
// Directives
using LocalDatabaseSample.Model;
using LocalDatabaseSample.ViewModel;
namespace LocalDatabaseSample
{
public partial class App : Application
{
/// <summary>
/// Provides easy access to the root frame of the Phone Application.
/// </summary>
/// <returns>The root frame of the Phone Application.</returns>
public PhoneApplicationFrame RootFrame { get; private set; }
// The static ViewModel, to be used across the application.
private static AnimalViewModel viewModel;
public static AnimalViewModel ViewModel
{
get { return viewModel; }
}
/// <summary>
/// Constructor for the Application object.
/// </summary>
public App()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
// Standard Silverlight initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode,
// which shows areas of a page that are handed off to GPU with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
// Disable the application idle detection by setting the UserIdleDetectionMode property of the
// application's PhoneApplicationService object to Disabled.
// Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
// and consume battery power when the user is not using the phone.
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
// Specify the local database connection string.
string DBConnectionString = "Data Source=isostore:/Animal.sdf";
// Create the database if it does not exist.
using (AnimalDataContext db = new AnimalDataContext(DBConnectionString))
{
if (db.DatabaseExists() == false)
{
// Create the local database.
db.CreateDatabase();
// Prepopulate the categories.
db.Categories.InsertOnSubmit(new AnimalCategory { Name = "Птицы" });
db.Categories.InsertOnSubmit(new AnimalCategory { Name = "Пресмыкающиеся" });
db.Categories.InsertOnSubmit(new AnimalCategory { Name = "Рыбы" });
// Save categories to the database.
db.SubmitChanges();
}
}
// Create the ViewModel object.
viewModel = new AnimalViewModel(DBConnectionString);
// Query the local database and load observable collections.
viewModel.LoadCollectionsFromDatabase();
}
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
}
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
}
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
}
// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
}
// Code to execute if a navigation fails
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// A navigation has failed; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
#region Phone application initialization
// Avoid double-initialization
private bool phoneApplicationInitialized = false;
// Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
// Do not add any additional code to this method
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
#endregion
}
}
Создайте папку Model и разместите в ней файл кода AnimalDataContext.cs со следующим содержимым:
using System;
using System.ComponentModel;
using System.Data.Linq;
using System.Data.Linq.Mapping;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
namespace LocalDatabaseSample.Model
{
public class AnimalDataContext : DataContext
{
// Pass the connection string to the base class.
public AnimalDataContext(string connectionString)
: base(connectionString)
{ }
// Specify a table for the Animal items.
public Table<AnimalItem> Items;
// Specify a table for the categories.
public Table<AnimalCategory> Categories;
}
[Table]
public class AnimalItem : INotifyPropertyChanged, INotifyPropertyChanging
{
// Define ID: private field, public property, and database column.
private int _AnimalItemId;
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity",
CanBeNull = false, AutoSync = AutoSync.OnInsert)]
public int AnimalItemId
{
get { return _AnimalItemId; }
set
{
if (_AnimalItemId != value)
{
NotifyPropertyChanging("AnimalItemId");
_AnimalItemId = value;
NotifyPropertyChanged("AnimalItemId");
}
}
}
// Define item name: private field, public property, and database column.
private string _itemName;
[Column]
public string ItemName
{
get { return _itemName; }
set
{
if (_itemName != value)
{
NotifyPropertyChanging("ItemName");
_itemName = value;
NotifyPropertyChanged("ItemName");
}
}
}
// Define completion value: private field, public property, and database column.
private bool _isComplete;
[Column]
public bool IsComplete
{
get { return _isComplete; }
set
{
if (_isComplete != value)
{
NotifyPropertyChanging("IsComplete");
_isComplete = value;
NotifyPropertyChanged("IsComplete");
}
}
}
// Internal column for the associated AnimalCategory ID value
[Column]
internal int _categoryId;
// Entity reference, to identify the AnimalCategory "storage" table
private EntityRef<AnimalCategory> _category;
// Association, to describe the relationship between this key and that "storage" table
[Association(Storage = "_category", ThisKey = "_categoryId",
OtherKey = "Id", IsForeignKey = true)]
public AnimalCategory Category
{
get { return _category.Entity; }
set
{
NotifyPropertyChanging("Category");
_category.Entity = value;
if (value != null)
{
_categoryId = value.Id;
}
NotifyPropertyChanging("Category");
}
}
// Version column aids update performance.
[Column(IsVersion = true)]
private Binary _version;
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Used to notify that a property changed
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region INotifyPropertyChanging Members
public event PropertyChangingEventHandler PropertyChanging;
// Used to notify that a property is about to change
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
#endregion
}
[Table]
public class AnimalCategory : INotifyPropertyChanged, INotifyPropertyChanging
{
// Define ID: private field, public property, and database column.
private int _id;
[Column(DbType = "INT NOT NULL IDENTITY", IsDbGenerated = true, IsPrimaryKey = true)]
public int Id
{
get { return _id; }
set
{
NotifyPropertyChanging("Id");
_id = value;
NotifyPropertyChanged("Id");
}
}
// Define category name: private field, public property, and database column.
private string _name;
[Column]
public string Name
{
get { return _name; }
set
{
NotifyPropertyChanging("Name");
_name = value;
NotifyPropertyChanged("Name");
}
}
// Define the entity set for the collection side of the relationship.
private EntitySet<AnimalItem> _Animals;
[Association(Storage = "_Animals", OtherKey = "_categoryId", ThisKey = "Id")]
public EntitySet<AnimalItem> Animals
{
get { return this._Animals; }
set { this._Animals.Assign(value); }
}
// Assign handlers for the add and remove operations, respectively.
public AnimalCategory()
{
_Animals = new EntitySet<AnimalItem>(
new Action<AnimalItem>(this.attach_Animal),
new Action<AnimalItem>(this.detach_Animal)
);
}
// Called during an add operation
private void attach_Animal(AnimalItem Animal)
{
NotifyPropertyChanging("AnimalItem");
Animal.Category = this;
}
// Called during a remove operation
private void detach_Animal(AnimalItem Animal)
{
NotifyPropertyChanging("AnimalItem");
Animal.Category = null;
}
// Version column aids update performance.
[Column(IsVersion = true)]
private Binary _version;
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Used to notify that a property changed
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region INotifyPropertyChanging Members
public event PropertyChangingEventHandler PropertyChanging;
// Used to notify that a property is about to change
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
#endregion
}
}
Создайте папку ViewModel и разместите в ней файл AnimalViewModel.cs со следующим содержимым:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
/*
Copyright (c) 2011 Microsoft Corporation. All rights reserved.
Use of this sample source code is subject to the terms of the Microsoft license
agreement under which you licensed this sample source code and is provided AS-IS.
If you did not accept the terms of the license agreement, you are not authorized
to use this sample source code. For the terms of the license, please see the
license agreement between you and Microsoft.
*/
// Directive for the data model.
using LocalDatabaseSample.Model;
namespace LocalDatabaseSample.ViewModel
{
public class AnimalViewModel : INotifyPropertyChanged
{
// LINQ to SQL data context for the local database.
private AnimalDataContext AnimalDB;
// Class constructor, create the data context object.
public AnimalViewModel(string AnimalDBConnectionString)
{
AnimalDB = new AnimalDataContext(AnimalDBConnectionString);
}
// All to-do items.
private ObservableCollection<AnimalItem> _allAnimalItems;
public ObservableCollection<AnimalItem> AllAnimalItems
{
get { return _allAnimalItems; }
set
{
_allAnimalItems = value;
NotifyPropertyChanged("AllAnimalItems");
}
}
// Animal items associated with the Birds category.
private ObservableCollection<AnimalItem> _BirdsAnimalItems;
public ObservableCollection<AnimalItem> BirdsAnimalItems
{
get { return _BirdsAnimalItems; }
set
{
_BirdsAnimalItems = value;
NotifyPropertyChanged("BirdsAnimalItems");
}
}
// Animal items associated with the Reptiles category.
private ObservableCollection<AnimalItem> _ReptilesAnimalItems;
public ObservableCollection<AnimalItem> ReptilesAnimalItems
{
get { return _ReptilesAnimalItems; }
set
{
_ReptilesAnimalItems = value;
NotifyPropertyChanged("ReptilesAnimalItems");
}
}
// Animal items associated with the Fishes category.
private ObservableCollection<AnimalItem> _FishesAnimalItems;
public ObservableCollection<AnimalItem> FishesAnimalItems
{
get { return _FishesAnimalItems; }
set
{
_FishesAnimalItems = value;
NotifyPropertyChanged("FishesAnimalItems");
}
}
// A list of all categories, used by the add task page.
private List<AnimalCategory> _categoriesList;
public List<AnimalCategory> CategoriesList
{
get { return _categoriesList; }
set
{
_categoriesList = value;
NotifyPropertyChanged("CategoriesList");
}
}
// Query database and load the collections and list used by the pivot pages.
public void LoadCollectionsFromDatabase()
{
// Specify the query for all to-do items in the database.
var AnimalItemsInDB = from AnimalItem Animal in AnimalDB.Items
select Animal;
// Query the database and load all to-do items.
AllAnimalItems = new ObservableCollection<AnimalItem>(AnimalItemsInDB);
// Specify the query for all categories in the database.
var AnimalCategoriesInDB = from AnimalCategory category in AnimalDB.Categories
select category;
// Query the database and load all associated items to their respective collections.
foreach (AnimalCategory category in AnimalCategoriesInDB)
{
switch (category.Name)
{
case "Птицы":
BirdsAnimalItems = new ObservableCollection<AnimalItem>(category.Animals);
break;
case "Пресмыкающиеся":
ReptilesAnimalItems = new ObservableCollection<AnimalItem>(category.Animals);
break;
case "Рыбы":
FishesAnimalItems = new ObservableCollection<AnimalItem>(category.Animals);
break;
default:
break;
}
}
// Load a list of all categories.
CategoriesList = AnimalDB.Categories.ToList();
}
// Add an Animal item to the database and collections.
public void AddAnimalItem(AnimalItem newAnimalItem)
{
// Add an Animal item to the data context.
AnimalDB.Items.InsertOnSubmit(newAnimalItem);
// Save changes to the database.
AnimalDB.SubmitChanges();
// Add an Animal item to the "all" observable collection.
AllAnimalItems.Add(newAnimalItem);
// Add an Animal item to the appropriate filtered collection.
switch (newAnimalItem.Category.Name)
{
case "Птицы":
BirdsAnimalItems.Add(newAnimalItem);
break;
case "Пресмыкающиеся":
ReptilesAnimalItems.Add(newAnimalItem);
break;
case "Рыбы":
FishesAnimalItems.Add(newAnimalItem);
break;
default:
break;
}
}
// Remove an Animal task item from the database and collections.
public void DeleteAnimalItem(AnimalItem AnimalForDelete)
{
// Remove the Animal item from the "all" observable collection.
AllAnimalItems.Remove(AnimalForDelete);
// Remove the Animal item from the data context.
AnimalDB.Items.DeleteOnSubmit(AnimalForDelete);
// Remove the Animal item from the appropriate category.
switch (AnimalForDelete.Category.Name)
{
case "Птицы":
BirdsAnimalItems.Remove(AnimalForDelete);
break;
case "Пресмыкающиеся":
ReptilesAnimalItems.Remove(AnimalForDelete);
break;
case "Рыбы":
FishesAnimalItems.Remove(AnimalForDelete);
break;
default:
break;
}
// Save changes to the database.
AnimalDB.SubmitChanges();
}
// Write changes in the data context to the database.
public void SaveChangesToDB()
{
AnimalDB.SubmitChanges();
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Used to notify Silverlight that a property has changed.
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
Запустите проект, нажав клавишу F5. Нажмите на кнопку Start, затем выберите пункт SETTINGS:
Выберите пункт Region + Language, В разделе Display language выберите русский язык:
Сохраните настройки.
Вернитесь в приложение LocalDataBaseSample. Поработайте с базой данных.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.