エクスポート (0) 印刷
すべて展開
情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

Windows Phone 8 の基本的なローカル データベース アプリを作成する方法

2014/06/18

対象: Windows Phone 8 および Windows Phone Silverlight 8.1 | Windows Phone OS 7.1

 

Windows Phone OS 7.1 以降、アプリのローカル フォルダーに存在するローカル データベースにリレーショナル データを格納できます。このトピックでは、1 ページだけの基本的な To Do リスト アプリの作成手順を通して、ローカル データベースを使用してデータを保存する方法を説明します。Windows Phone アプリでのローカル データベースの使用の詳細については、「Windows Phone 8 のローカル データベース」を参照してください。

ヒントヒント:

このアプリに、他のデータベース テーブルやアプリ ページを追加し、さらにピボット コントロールや Windows Phone Toolkit を組み合わせて、MVVM (Model-View-ViewModel) パターンを使用して実装する方法については、「Windows Phone 8 用の MVVM でローカル データベース アプリを作成する方法」を参照してください。

このアプリが完成したときの表示の例を、次の図に示します。

AP_Con_IStorage_DB2

テキスト ボックスにテキストを入力して [add] をタッチすると、To Do アイテムがアプリ内のリストに追加されます。削除アイコンをタッチすると、アイテムがリストから削除されます。To Do アイテムはローカル データベースに保存されているので、リスト内の値はアプリを終了しても消えることはありません。

このトピックは、次のセクションで構成されています。

 

このセクションでは、アプリ プロジェクトを作成してから、ユーザー インターフェイスを作成します。

アプリの UI を作成するには

  1. Windows Phone SDK を開き、[Windows Phone アプリ ] テンプレートを使用して新しいプロジェクトを作成します。

  2. プロジェクトを作成した後、[プロジェクト] メニューの [既存項目の追加] をクリックします。[既存の項目の追加] メニューが表示されます。次の手順で、To Do アイテムを削除するためのアイコンをこのメニューから選択します。

  3. [既存の項目の追加] ウィンドウで、次のパスに移動して appbar.delete.rest.png という名前のアイコンを選択します。このアイコンのデザインは、暗い背景色に合わせて白が採用されているため、[既存の項目の追加] ウィンドウの白い背景色の上では、何もないように見えるかもしれません。

    C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Icons\dark

    メモメモ:

    この手順では、Visual Studio の既定のインストールを想定しています。別の場所にインストールしている場合は、対応する場所でアイコンを見つけます。

  4. [追加] をクリックします。アイコンがソリューション エクスプローラーの一覧に追加されます。

  5. ソリューション エクスプローラーで、アイコンを右クリックし、アイコンが [コンテンツ] として構築され、常に出力ディレクトリにコピーされる ([常にコピーする]) ように、ファイルのプロパティを設定します。

  6. MainPage.xaml の中で、LayoutRoot という名前の Grid の XAML コードを削除し、次に示すコードで置き換えます。

    <!--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="LOCAL DATABASE EXAMPLE" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="to-do list" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
            <!--ContentPanel - place additional content here.-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                
                <!-- Bind the list box to the observable collection. -->
                <ListBox x:Name="toDoItemsListBox" ItemsSource="{Binding ToDoItems}" 
                         Grid.Row="0" Margin="12, 0, 12, 0" Width="440">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid HorizontalAlignment="Stretch" Width="440">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="50" />
                                    <ColumnDefinition Width="*" />                               
                                    <ColumnDefinition Width="100" />                                
                                </Grid.ColumnDefinitions>
                                <CheckBox
                                    IsChecked="{Binding IsComplete, Mode=TwoWay}"
                                    Grid.Column="0"
                                    VerticalAlignment="Center"/>
                                <TextBlock
                                    Text="{Binding ItemName}"
                                    FontSize="{StaticResource PhoneFontSizeLarge}"
                                    Grid.Column="1"
                                    VerticalAlignment="Center"/>
                                <Button
                                    Grid.Column="2"
                                    x:Name="deleteTaskButton"
                                    BorderThickness="0"                                
                                    Margin="0"
                                    Click="deleteTaskButton_Click">
                                    <Image Source="appbar.delete.rest.png"/>                                
                                </Button>
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>      
                
                <Grid Grid.Row="1">                
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <TextBox
                        x:Name="newToDoTextBox"                    
                        Grid.Column="0"
                        Text="add new task"
                        FontFamily="{StaticResource PhoneFontFamilyLight}"                    
                        GotFocus="newToDoTextBox_GotFocus"/>
                    <Button 
                        Content="add"
                        Grid.Column="1"
                        x:Name="newToDoAddButton"
                        Click="newToDoAddButton_Click"/>                
                </Grid>
            </Grid>
        </Grid>
    
    

    この XAML コードによって、2 つの Grid 要素がアプリに追加されます。一方のグリッドには toDoItemsListBox があり、ここに To Do アイテムが一覧表示されます。このリストにバインドされた To Do アイテムの数が増えるにつれて、ListBox のサイズが大きくなり、2 つ目のグリッドが画面の下の方に移動します。もう 1 つの Grid 要素には、newToDoTextBoxButton があり、新しい To Do アイテムを入力できるようになっています。

このセクションでは、データベース スキーマを決定するオブジェクト モデルを指定し、データ コンテキストを作成します。

データ コンテキストを作成するには

  1. メイン ページの分離コード ファイル (MainPage.xaml.cs) を開きます。このページに、アプリ ロジックのほとんどの部分を記述します。このアプリは、わかりやすくするためにページは 1 つだけとなっています。実際のアプリでは、多くの場合、MVVM (Model-View-ViewModel) プログラミング パターンが使用されます。詳細については、「Windows Phone 8 での Model-View-ViewModel パターンの実装」を参照してください。

  2. このアプリには、Windows Phone 用の LINQ to SQL アセンブリへの参照が必要です。[プロジェクト] メニューの [参照の追加] をクリックし、[アセンブリ/フレームワーク] リストの [System.Data.Linq] を選択して、[OK] をクリックします。

    メモメモ:

    Windows Phone 8 が対象の場合、このアセンブリは Windows Phone アプリ テンプレートを使用する新しいアプリで自動的に参照されます。

  3. ページの先頭に、次のディレクティブを追加します。

    using System.Data.Linq;
    using System.Data.Linq.Mapping;
    using System.ComponentModel;
    using System.Collections.ObjectModel;
    
    
  4. MainPage クラスの下に、次のコードを追加します。このエンティティ クラス ToDoItem は、ローカル データベース内にある、このアプリのデータベース テーブルを表します。このクラスは、変更追跡のための INotifyPropertyChanged を実装します。INotifyPropertyChanging を実装するのは、変更追跡に関連したメモリ消費が上限を超えないようにするためです。テーブル属性 [Table] は、このクラスをローカル データベース テーブルにマッピングすることを LINQ to SQL ランタイムに指示するものです。

    [Table]
    public class ToDoItem : INotifyPropertyChanged, INotifyPropertyChanging
    {
    // Define ID: private field, public property and database column.
    private int _toDoItemId;
    
    [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int ToDoItemId
    {
        get
        {
            return _toDoItemId;
        }
        set
        {
            if (_toDoItemId != value)
            {
                NotifyPropertyChanging("ToDoItemId");
                _toDoItemId = value;
                NotifyPropertyChanged("ToDoItemId");
            }
        }
    }
    
    // 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");
            }
        }
    }
    // Version column aids update performance.
    [Column(IsVersion = true)]
    private Binary _version;
    
    #region INotifyPropertyChanged Members
    
    public event PropertyChangedEventHandler PropertyChanged;
    
    // Used to notify the page that a data context 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 the data context that a data context property is about to change
    private void NotifyPropertyChanging(string propertyName)
    {
        if (PropertyChanging != null)
        {
            PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
        }
    }
    
    #endregion
    }
    
    

    ToDoItem クラスには 3 つのパブリック プロパティがあり、これらは次のように 3 つのデータベース列に対応しています。

    • ToDoItemId: データベースによって自動的にデータが格納される ID 列。この列は主キーでもあり、この列に対してデータベース インデックスが自動的に作成されます。これらの設定およびその他の設定が、LINQ to SQL のプロパティ構文に従って Column マッピング属性で指定されています。

    • ItemName: To Do アイテムのテキストが格納される列。

    • IsComplete: To Do アイテムの完了状態が格納される列。

    重要:重要:

    変更追跡に必要なメモリ消費が上限を超えないようにするために、データ コンテキスト内のオブジェクトに対しては必ず INotifyPropertyChanging インターフェイスを実装してください。

  5. MainPage クラスの下に、次のコードを追加します。これは、ToDoDataContext という名前のクラスです。このクラスは、DataContext を継承しており、このクラスをデータ コンテキストと呼びます。最も重要なことは、このコードで基本コンストラクターを呼び出し、ToDoItems という名前のデータベース テーブルを宣言することです。

    public class ToDoDataContext : DataContext
    {
        // Specify the connection string as a static, used in main page and app.xaml.
        public static string DBConnectionString = "Data Source=isostore:/ToDo.sdf";
    
        // Pass the connection string to the base class.
        public ToDoDataContext(string connectionString)
            : base(connectionString)
        { }
    
        // Specify a single table for the to-do items.
        public Table<ToDoItem> ToDoItems;
    }
    
    
    メモメモ:

    データベース接続文字列は、静的フィールドでなくてもかまいませんが、この例では、便宜上静的フィールドとなっています。接続文字列の詳細については、「Windows Phone 8 のローカル データベース接続文字列」を参照してください。

このセクションでは、データベースがまだ存在しない場合にデータベースを作成するためのコードを追加します。

データベースを作成するには

  1. アプリの分離コード ファイル App.xaml.cs を開きます。この中に、アプリ オブジェクトのコードが格納されます。

  2. アプリ オブジェクトのコンストラクター App() の末尾に、次のコードを追加します。このデータベース作成コードをここに追加するのは、データベースが既に存在する状態でメイン ページのコードが実行されるようにするためです。

    // Create the database if it does not exist.
    using (ToDoDataContext db = new ToDoDataContext(ToDoDataContext.DBConnectionString))
    {
        if (db.DatabaseExists() == false)
        {
            //Create the database
            db.CreateDatabase();
        }
    }
    
    

    ToDoDataContext クラスのコンストラクター内で接続文字列に静的フィールドを使用しているのは、利便性のためです。これは、値 "Data Source=isostore:/ToDo.sdf" をコンストラクターに渡すのと同じことです。

このセクションでは、アプリ コードの残りの部分を完成させます。

アプリを完成させるには

  1. メイン ページの分離コード ファイル (MainPage.xaml.cs) を開きます。このファイルに、アプリの残りの部分が格納されます。

  2. MainPage クラスを、次に示すコードで置き換えます。データ バインドをサポートするために、このコードによって INotifyPropertyChanged インターフェイスを MainPage クラスのシグネチャに追加し、さらに対応する INotifyPropertyChanged メンバーを追加します。

    public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
    {
    
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
    
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        // Used to notify the app that a property has changed.
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }
    
    
  3. MainPage クラスのクラス コンストラクターの上に、次のコードを追加します。このコードでは、プライベート データ コンテキスト toDoDB と、 ObservableCollection 型のパブリック プロパティ ToDoItems を宣言します。ToDoItems は、データを UI にバインドするために使用されます。

    // Data context for the local database
    private ToDoDataContext toDoDB;
    
    // Define an observable collection property that controls can bind to.
    private ObservableCollection<ToDoItem> _toDoItems;
    public ObservableCollection<ToDoItem> ToDoItems
    {
        get
        {
            return _toDoItems;
        }
        set
        {
            if (_toDoItems != value)
            {
                _toDoItems = value;
                NotifyPropertyChanged("ToDoItems");
            }
        }
    }
    
    
  4. MainPage クラス コンストラクター内で、InitializeComponent の呼び出しの下に次のコードを追加します。このコードでは、ローカル データベースのデータ コンテキストをインスタンス化しますが、ここでも静的な接続文字列 DBConnectionString を使用します。また、メイン ページを、ページ データ コンテキストのルートとして設定します。

    // Connect to the database and instantiate data context.
    toDoDB = new ToDoDataContext(ToDoDataContext.DBConnectionString);
                
    // Data context and observable collection are children of the main page.
    this.DataContext = this;
    
    
  5. MainPage クラスで、クラス コンストラクターの下に次のコードを追加します。ユーザーがこのページを開くと、このコードによってローカル データベースに対するクエリが実行されて、結果が ToDoItems コレクションに格納されます。データ バインドが XAML の中で構成されているので、toDoItemsListBox コントロールには、対応する To Do アイテムが自動的に格納されます。

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
    // Define the query to gather all of the to-do items.
    var toDoItemsInDB = from ToDoItem todo in toDoDB.ToDoItems
                        select todo;
    
    // Execute the query and place the results into a collection.
    ToDoItems = new ObservableCollection<ToDoItem>(toDoItemsInDB);
                
        // Call the base method.
        base.OnNavigatedTo(e);
    }
    
    
  6. MainPage クラスで、クラス コンストラクターの下に次のコードを追加します。このコードは、To Do アイテムをデータベースに追加するためのものです。newToDoTextBox_GotFocus によってテキスト ボックスの内容が消去された後で、ユーザーが To Do アイテムのテキストを入力します。newToDoAddButton_Click によって新しい ToDoItem オブジェクトが作成され、このオブジェクトが ToDoItems コレクションと toDoDB データ コンテキストに追加されます。ユーザーが別のページに移動して SubmitChanges メソッドが呼び出されると、新しい To Do アイテムが実際にローカル データベースに追加されます。

    private void newToDoTextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        // Clear the text box when it gets focus.
        newToDoTextBox.Text = String.Empty;
    }
    
    private void newToDoAddButton_Click(object sender, RoutedEventArgs e)
    {
        // Create a new to-do item based on the text box.
        ToDoItem newToDo = new ToDoItem { ItemName = newToDoTextBox.Text };
    
        // Add a to-do item to the observable collection.
        ToDoItems.Add(newToDo);
                
        // Add a to-do item to the local database.
        toDoDB.ToDoItems.InsertOnSubmit(newToDo);          
    }
    
    protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
    {
        // Call the base method.
        base.OnNavigatedFrom(e);
    
        // Save changes to the database.
        toDoDB.SubmitChanges();
    }
    
    
    重要:重要:

    データ コンテキストに追加された新しい項目がデータベースに保存されるのは、SubmitChanges メソッドが呼び出されたときです。

  7. MainPage クラスで、クラス コンストラクターの下に次のコードを追加します。このコードが呼び出されるのは、ユーザーが削除アイコンを押したときです。このコードによって、対応する To Do アイテムを ToDoItems コレクションと toDoDB データ コンテキストから削除します。削除された To Do アイテムは、SubmitChanges メソッドが呼び出されたときに実際にローカル データベースから削除されます。

    private void deleteTaskButton_Click(object sender, RoutedEventArgs e)
    {
        // Cast parameter as a button.
        var button = sender as Button;
    
        if (button != null)
        {
            // Get a handle for the to-do item bound to the button.
            ToDoItem toDoForDelete = button.DataContext as ToDoItem;
    
            // Remove the to-do item from the observable collection.
            ToDoItems.Remove(toDoForDelete);
    
            // Remove the to-do item from the local database.
            toDoDB.ToDoItems.DeleteOnSubmit(toDoForDelete);
    
            // Save changes to the database.
            toDoDB.SubmitChanges();
    
            // Put the focus back to the main page.
            this.Focus();
        }
    }
    
    
    重要:重要:

    データ コンテキストから削除された項目がデータベースから削除されるのは、SubmitChanges メソッドが呼び出されたときです。

  8. これでアプリが完成しました。F5 キーを押してデバッグを開始し、アプリをテストします。

表示:
© 2015 Microsoft