2012-02-06
その15:ApplicationDataContainerを使ってデータを保存する
連載:Developer Previewでも強気で進めるMetroStyleApp超入門
Windows 8 Developer Previewなので正式版とは異なる場合があります。 また、Windows Updateが走るときもあるため、エントリ執筆現在の情報をもとにかいています。
ApplicationDataContainerは一言で言えばSLとかWPでいうIsolatedStorageです。
今回はInternal static classを使って、Page間でよべるように(というかアプリケーション内ならどこでも)しました。
2つのページにRead用とSave用のButtonとTextBlock/Boxがあって、どちらからでも書き込んだり読んだりできます。
using System; using System.Threading.Tasks; using Windows.ApplicationModel.Activation; using Windows.UI.Xaml; using Windows.Storage; namespace Application20 { partial class App { public App() { InitializeComponent(); } protected override void OnLaunched(LaunchActivatedEventArgs args) { Window.Current.Content = new MainPage(); Window.Current.Activate(); } } internal static class PublicData { // internal static String PublicString; // internal static float PublicFloat; //分離ストレージを作成 ここのデータはアプリを落としても消えない。 internal static ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; } }
MainPage.xaml
<UserControl x:Class="Application20.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="1366"> <Grid x:Name="LayoutRoot" Background="DarkBlue"> <StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal"> <TextBlock Width="200" x:Name="ReadTextBlock"></TextBlock> <Button Content="Read" Click="ReadButton_Click"></Button> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBox Width="200" x:Name="SaveTextBox"></TextBox> <Button Content="Save" Click="SaveButton_Click"></Button> </StackPanel> </StackPanel> <Frame Width="500" Source="Application20.BlankPage1"></Frame> </Grid> </UserControl>
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Data; namespace Application20 { partial class MainPage { public MainPage() { InitializeComponent(); } private void ReadButton_Click(object sender, RoutedEventArgs e) { ReadTextBlock.Text = (String)PublicData.localSettings.Values["Text"]; } private void SaveButton_Click(object sender, RoutedEventArgs e) { PublicData.localSettings.Values["Text"] = SaveTextBox.Text; } } }
BlankPage1.xaml
<Page x:Class="Application20.BlankPage1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="1366" d:DesignHeight="768"> <!--Common resources for default dark theme applications--> <UserControl.Resources> <SolidColorBrush x:Key="PageBackgroundBrush" Color="#FF1A1A1A"/> <SolidColorBrush x:Key="PageForegroundBrush" Color="White"/> <SolidColorBrush x:Key="HighlightBrush" Color="#FF26A0DA"/> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="{StaticResource PageBackgroundBrush}"> <Grid> <StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal"> <TextBlock Width="200" x:Name="ReadTextBlock"></TextBlock> <Button Content="Read" Click="ReadButton_Click"></Button> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBox Width="200" x:Name="SaveTextBox"></TextBox> <Button Content="Save" Click="SaveButton_Click"></Button> </StackPanel> </StackPanel> </Grid> </Grid> </Page>
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Windows.Foundation; using Windows.Graphics.Display; using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Data; namespace Application20 { public sealed partial class BlankPage1 { public BlankPage1() { InitializeComponent(); } private void ReadButton_Click(object sender, RoutedEventArgs e) { ReadTextBlock.Text = (String)PublicData.localSettings.Values["Text"]; } private void SaveButton_Click(object sender, RoutedEventArgs e) { PublicData.localSettings.Values["Text"] = SaveTextBox.Text; } } }
その14:Frame in FrameでPopup風デザインを実装する
連載:Developer Previewでも強気で進めるMetroStyleApp超入門
Windows 8 Developer Previewなので正式版とは異なる場合があります。 また、Windows Updateが走るときもあるため、エントリ執筆現在の情報をもとにかいています。
その13で紹介したMessageDialogは文字列を表示するためのものでした。
今回はFrame in Frameを使って、PopupなWindowを実装します。
とりあえずこんなかんじ。
ボタンを押すとー
FrameにホストされたPageが表示されます。
まず、MainPage.xaml
Frameコントロールだけ設置したUserControlです。
デフォルトでMainFrame.xamlがホストされてます。
<UserControl x:Class="Application19.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="1366"> <Grid x:Name="LayoutRoot" Background="Black"> <Frame x:Name="Frame" Source="Application19.MainFrame"></Frame> </Grid> </UserControl>
で、これがMainFrame.xaml。緑色の画面ですね。
Frameを非表示で設置しています。
<Page x:Class="Application19.MainFrame"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Loaded="Page_Loaded" Unloaded="Page_Unloaded"
mc:Ignorable="d"
d:DesignWidth="1366" d:DesignHeight="768">
<!--Common resources for default dark theme applications-->
<UserControl.Resources>
<SolidColorBrush x:Key="PageBackgroundBrush" Color="#FF1A1A1A"/>
<SolidColorBrush x:Key="PageForegroundBrush" Color="White"/>
<SolidColorBrush x:Key="HighlightBrush" Color="#FF26A0DA"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Green">
<Button Content="Show Popup Frame" HorizontalAlignment="Center" FontSize="80" Click="Button_Click"></Button>
<Frame x:Name="Frame" Visibility="Collapsed"></Frame>
</Grid>
</Page>
ボタンがクリックされると、Page内にあるFrameにPopupFrame.xamlを表示します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Graphics.Display;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
namespace Application19
{
public sealed partial class MainFrame
{
public MainFrame()
{
InitializeComponent();
}
// View state management for switching among Full, Fill, Snapped, and Portrait states
private DisplayPropertiesEventHandler _displayHandler;
private TypedEventHandler<ApplicationLayout, ApplicationLayoutChangedEventArgs> _layoutHandler;
private void Page_Loaded(object sender, RoutedEventArgs e)
{
if (_displayHandler == null)
{
_displayHandler = Page_OrientationChanged;
_layoutHandler = Page_LayoutChanged;
}
DisplayProperties.OrientationChanged += _displayHandler;
ApplicationLayout.GetForCurrentView().LayoutChanged += _layoutHandler;
SetCurrentOrientation(this);
}
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
DisplayProperties.OrientationChanged -= _displayHandler;
ApplicationLayout.GetForCurrentView().LayoutChanged -= _layoutHandler;
}
private void Page_LayoutChanged(object sender, ApplicationLayoutChangedEventArgs e)
{
SetCurrentOrientation(this);
}
private void Page_OrientationChanged(object sender)
{
SetCurrentOrientation(this);
}
private void SetCurrentOrientation(Control viewStateAwareControl)
{
VisualStateManager.GoToState(viewStateAwareControl, this.GetViewState(), false);
}
private String GetViewState()
{
var orientation = DisplayProperties.CurrentOrientation;
if (orientation == DisplayOrientations.Portrait ||
orientation == DisplayOrientations.PortraitFlipped) return "Portrait";
var layout = ApplicationLayout.Value;
if (layout == ApplicationLayoutState.Filled) return "Fill";
if (layout == ApplicationLayoutState.Snapped) return "Snapped";
return "Full";
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Frame.Visibility = Visibility.Visible;
Frame.Navigate("Application19.PopupFrame");
}
}
}
最後に、PopupPage.xamlです。
一番大きいGridを半透明にし、中にコンテンツを表示する小さいGridを設置します。
小さいGridの方に、表示したい内容を書きます。
<Page x:Class="Application19.PopupFrame" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Loaded="Page_Loaded" Unloaded="Page_Unloaded" mc:Ignorable="d" d:DesignWidth="1366" d:DesignHeight="768"> <!--Common resources for default dark theme applications--> <UserControl.Resources> <SolidColorBrush x:Key="PageBackgroundBrush" Color="#FF1A1A1A"/> <SolidColorBrush x:Key="PageForegroundBrush" Color="White"/> <SolidColorBrush x:Key="HighlightBrush" Color="#FF26A0DA"/> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="#991A1A1A"> <Grid Width="680" Height="420" Background="#FF1A00BB"> <Button Content="Close Popup" Click="Button_Click" HorizontalAlignment="Center"></Button> </Grid> </Grid> </Page>
ボタンがクリックされると、自身のFrameを非表示にします。
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Windows.Foundation; using Windows.Graphics.Display; using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Data; namespace Application19 { public sealed partial class PopupFrame { public PopupFrame() { InitializeComponent(); } // View state management for switching among Full, Fill, Snapped, and Portrait states private DisplayPropertiesEventHandler _displayHandler; private TypedEventHandler<ApplicationLayout, ApplicationLayoutChangedEventArgs> _layoutHandler; private void Page_Loaded(object sender, RoutedEventArgs e) { if (_displayHandler == null) { _displayHandler = Page_OrientationChanged; _layoutHandler = Page_LayoutChanged; } DisplayProperties.OrientationChanged += _displayHandler; ApplicationLayout.GetForCurrentView().LayoutChanged += _layoutHandler; SetCurrentOrientation(this); } private void Page_Unloaded(object sender, RoutedEventArgs e) { DisplayProperties.OrientationChanged -= _displayHandler; ApplicationLayout.GetForCurrentView().LayoutChanged -= _layoutHandler; } private void Page_LayoutChanged(object sender, ApplicationLayoutChangedEventArgs e) { SetCurrentOrientation(this); } private void Page_OrientationChanged(object sender) { SetCurrentOrientation(this); } private void SetCurrentOrientation(Control viewStateAwareControl) { VisualStateManager.GoToState(viewStateAwareControl, this.GetViewState(), false); } private String GetViewState() { var orientation = DisplayProperties.CurrentOrientation; if (orientation == DisplayOrientations.Portrait || orientation == DisplayOrientations.PortraitFlipped) return "Portrait"; var layout = ApplicationLayout.Value; if (layout == ApplicationLayoutState.Filled) return "Fill"; if (layout == ApplicationLayoutState.Snapped) return "Snapped"; return "Full"; } private void Button_Click(object sender, RoutedEventArgs e) { this.Frame.Visibility = Visibility.Collapsed; } } }
これでPopupなデザインが実現できました。
簡単ですね。
その13:MessageDialogを表示する
連載:Developer Previewでも強気で進めるMetroStyleApp超入門
Windows 8 Developer Previewなので正式版とは異なる場合があります。 また、Windows Updateが走るときもあるため、エントリ執筆現在の情報をもとにかいています。
MetroStyleAppsにはMessageBoxはありません。
かわりにMessageDialogが存在します。
見た目はこんなかんじ。
MessageDialog.Show()とか出来たらいいんですが、それではできなくてこんなふうにかきます。
<UserControl x:Class="Application19.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="1366"> <Grid x:Name="LayoutRoot" Background="Green"> <Button Content="MessageDialogButton" Click="Button_Click" HorizontalAlignment="Center"></Button> </Grid> </UserControl>
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Data; using Windows.UI.Popups; namespace Application19 { partial class MainPage { public MainPage() { InitializeComponent(); } private async void Button_Click(object sender, RoutedEventArgs e) { var md = new MessageDialog("Hello Metro"); await md.ShowAsync(); } } }
C#のコードからもわかるように、MessageDialogを使う場合は、private asyncとなります。
また、MessageDialog.ShowAsync()するまえにawaitを記述します。
これは、MessageDialogを表示する際に、後ろに表示してある画面を一旦ストップさせている(というかMessageDialogが割り込んで処理している)から、非同期の処理になるものだと思われます。
あとはusingに
が追加されているのもポイントね!






