<   2013年 12月 ( 1 )   > この月の画像一覧

XAML関係 - データバインドと非同期 (12/2)

データバインドという以前XAMLでビヘイビアとして記述でき、デザインにアクションが書ける機能が面白いなと思っていたので、復習しようと思ったら、非同期に組み合わせると、Win8のストアアプリの基本らしいとの事。

どうやら従来デスクトップアプリではWindowsイベントループでUI更新していたが、
ストアアプリは上記の通りらしい。

@IT - 文字列をコントロールにバインドするには?[Win 8/WP 8]

で、その例をXP用(.NET 4.0)にしてみた。(データバインドをメインに)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel; // INotifyPropertyChanged継承用
using System.Threading.Tasks; // .NET 4.0 XP用
using System.Threading; // .NET 4.0 XP用

namespace WpfApplication1
{
// MainWindow:コントロールに対する非同期処理を
// データバインド(⇔イベントループではなく)で実装する例
// TextBlockコントロールに時間表示(10ms)
// .NET 4.5用のasyncの代わりに.NET 4.0 XPでも使えるTaskクラスに置き換えた


public partial class MainWindow : Window
{
private Clock _clock1 = new Clock();

public MainWindow() // MainPage=ストアアプリ : MainWin=デスクトップ
{
this.InitializeComponent();

// データバインドを利用せずイベントを使った実装の場合
//_clock1.PropertyChanged += clock1_PropertyChanged;

// データバインドをXMLに記述しない場合
//var tbBind = new Binding()
//{
// Source = _clock1 ,
// Path = new PropertyPath ( "NowTime" ) ,
//};
//textClock1.SetBinding ( TextBlock.TextProperty, tbBind);

textClock1.DataContext = _clock1;
}

// データバインドを利用せずイベントを使った実装の場合
//void clock1_PropertyChanged(object sender,
// System.ComponentModel.PropertyChangedEventArgs e)
//{
// textClock1.Text = _clock1.NowTime;
//}
}
public class Clock : INotifyPropertyChanged
{
public string NowTime { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;

public Clock()
{
//Run(); // .NET 4.5 Win7以上
Task.Factory.StartNew(() => Run()); // .NET 4.0 XP用

}
// .NET 4.5 Win7以上
//private async void Run()
//{
// DateTimeOffset lastTime;
// while(true)
// {
// await Task.Delay(10);
// :
// }
//}
// .NET 4.0 XP用
private void Run()
{
DateTimeOffset lastTime = DateTimeOffset.Now; // 初期化追加
while (true)
{
Thread.Sleep(10);
var nowTime = DateTimeOffset.Now;
if (lastTime.Second != nowTime.Second)
{
this.NowTime = nowTime.ToString("HH:mm:ss");
if (this.PropertyChanged != null)
this.PropertyChanged(this, new
PropertyChangedEventArgs("NowTime"));
lastTime = nowTime;
}
}
}
}
}

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid Background="Black">
<TextBlock x:Name="textClock1" Text="{Binding NowTime}" Height="120"
HorizontalAlignment="Left" Margin="52,40,0,0"
VerticalAlignment="Top" Width="414" FontSize="120"
Foreground="LimeGreen" />
</Grid>
</Window>

Taskクラスとかすっごい便利。.NETに移行した時ついでにC#も覚えたけど、
C#や.NETにどんどん便利な機能が追加されていて勉強不足を感じる。
Webばかりでなくアプリケーションもまだまだ面白いよ。
(VS2010ExpressC#WPFアプリ)
[PR]
by k1segawa | 2013-12-02 23:44 | Comments(0)