Quantcast
Channel: かずきのBlog@hatena
Viewing all 1388 articles
Browse latest View live

Azure MLで天気予報をしてみた #azurejp #jazug

$
0
0

Azure MLで天気予報してみよう(占いくらいの精度のやつ)

ということで、気象庁の過去データから 天気概況(昼:06時~18時)を15年分落としてみました。

www.data.jma.go.jp

やることは月と日を入力したらなんと天気を出してくれる…!まぁ日付と天気には、相関そんな無いしあ~した天気にな~れくらいの精度だと思います。

ここでの目的は、何個かのインプットに対して結果を分類分け(今回の場合天気)してくれるというものにチャレンジするというところです。とりあえずダウンロードしたデータを以下のように加工してAzure MLのデータセットにあげました。

f:id:okazuki:20151008213347p:plain

天気予報という名前でEXPERIMENTSを作ります。そして、先ほどUPしたデータをぽとりと置いて、Project Columnsで必要なデータ(月、日、天気)に絞り込みます。

f:id:okazuki:20151008213550p:plain

Splitで7:3にデータを分割します。先ほどは、数値のデータを予測するのでRegressionの中からアルゴリズムを選択しましたが、今回は分類するのでClassificationから選びます。Classificationの中には分類項目が2つに特化したTwo-Class *というアルゴリズムと、分類項目が複数のMulticlass **というアルゴリズムがあります。今回の天気の結果は2つじゃないのでMulticlassのほうを使います。

有名どころでMulticlass Logistic Regressionを選びました。(大学のころロジスティックという言葉聞いた覚えがある)これを、Train Modelを使ってトレーニングしてScore Modelで結果を照合してEvalute Modelで評価します。大体こんな感じ。

f:id:okazuki:20151008214028p:plain

Train Modelが赤くなってるので結果の列である天気を選択してRUN!

Evalute Modelで評価結果をみるとズタボロです。

f:id:okazuki:20151008214429p:plain

1に近いほどいいとされるaccuracy, precision, recallがすごいことになってます。クロス表もボロボロ…。

f:id:okazuki:20151008215029p:plain

用意するデータって重要だというのがわかりますね。今回みたいに適当したらだめです。

Predictive Web ServicesでWebサービス化して、公開します。月、日が入力で予測結果が出力になるように微調整をかけてDEPLOY!

当たらない天気予報の出来上がりです。まぁ分類分けの練習ってことで…。


Azure MLでガジェクラかどうか判定してみよう #azurejp #jazug

$
0
0

たなかさんからこんな問い合わせがありました。

なので手動でインタビューをしてサンプリングしたのと一般人を大量投入したデータを作ってみました。

f:id:okazuki:20151008224617p:plain

おでさん(予測値)が際立ちますね。

クラスタリング

さて、教師なし学習の代表例?であるクラスタリング(要は分類)してみたいと思います。データをつっこむと勝手にデータをグルーピングしてくれるというやつですね。便利便利。

データのアップロード

先ほど作成したデータをML StudioのDATASETにアップします。

f:id:okazuki:20151008224948p:plain

EXPERIMENTSの作成

ガジェクラ判定機という名前でEXPERIMENTSを作成して先ほどアップしたガジェクラ誰だというDATASETを置きます。クラスタリングをしてくれるアルゴリズムはK-Means Clusteringというのがあります。こいつをぽとっと置きます。

クラスタリングのトレーニングはTrain Clustering Modelでやります。こいつをつなぎ合わせます。

Train Clustering Modelに赤いびっくりマークが出るので右側のLaunch column selectorでクラスタリングの判定に使う列名を指定します。今回は端末所持台数であるcountを選びます。

f:id:okazuki:20151008225420p:plain

これで、こんな感じになります。

f:id:okazuki:20151008225520p:plain

K-Means ClusteringでNumber of Centroidsの数字をいじると何個に分類分けするか決めることができます。今回はライトユーザー、ヘビーユーザー、廃人の3パターンくらいにわけたいので3を設定しました。

f:id:okazuki:20151008225727p:plain

最後に、結果を表示するためにProject Columnsで表示列を絞り込みます。Train Clustering Modelの右側のピンとつないでname, count, Assignmentsを選びます(Assignmentsが分類結果)

そしたら実行します。

実行してProject Columnsの出力をVisualizeすると以下のようになります。

f:id:okazuki:20151008230738p:plain

どうやら0がライトユーザー、1が廃人、2がヘビーユーザーと分類されたみたいです。(ここらへん分類にどういう名前つけるかは人の仕事)

では、SET UP WEB SERVICEでPredictive Web ServicesでWebサービス化しましょう。以下のような感じになります。

f:id:okazuki:20151008231211p:plain

ガジェクラ誰だとAssign Data to Clustersの間にProject Columnsを入れて入力をcountのみに絞り込みます。そしてAssign Data to ClustersとWeb service outputの間にProject Columnsを入れてAssignmentsのみに絞り込みます。(Assignmentsが出ない場合は適当な列を選んでから一度実行するといい)

RUNしてエラーがないことを確認したらDEPLOY WEB SERVICEをします。

Excelで動作確認

ダウンロードできるエクセルを使って動作確認をします。 0がライトユーザーで2がヘビーユーザーで1が廃人です。

1台持ちの人はライトユーザー。 f:id:okazuki:20151008232447p:plain

5台持ちの人はヘビーユーザー。 f:id:okazuki:20151008232559p:plain

15台持ちの人は廃人っぽいです。 f:id:okazuki:20151008232647p:plain

まとめ

スマートフォンの持ちすぎには注意しましょう。

ReactiveProperty v2.2.6をリリースしました

$
0
0

www.nuget.org

  • ReactiveCollectionにAddRangeOnSchedulerメソッドを追加しました。

平たく言うとIssueでリクエストが来たので。

github.com

Prism.WpfのドキュメントがMarkdownになりました

$
0
0

PDFでしかなかったPrismのWPF版のドキュメントがMarkdownになってGitHub上に放流されてました。

ドキュメントのトップはこちら。

github.com

WPFのドキュメントはこちら。まだ出来立てなので、画像のリンク切れとかおこしてたりしますが、おおむね大丈夫でしょう。

github.com

UWPをリモートデバッグする

$
0
0

タブレットでデバッグしてみたいとかWin8で開発したいとかそういうときに使います。

Remote Tools for Visual Studio 2015をDLしてデバッグしたいPCにインストールします。

Download Remote Tools for Visual Studio 2015 from Official Microsoft Download Center

インストールするとRemote Debuggerというのが追加されるので、それを起動します。

同じローカルのネットワークにつないだ状態で、リモートコンピュータを対象にデバッグ実行すると選択肢にPCが出きます。開発者ライセンスや対象PCへの接続情報を入力すると配置されてデバッグが開始できます。

AzureのEventHub -> Stream Analytics -> ServiceBus Queueのスルーパスでどれくらいのスピードなのか見てみた

$
0
0

@xin9leさんと話しをしてて、EventHubに突っ込んだデータがStream Analyticsが処理してQueueに突っ込んだ結果どれくらいで返ってくるものなのかという話しになりました。 なので、まぁ適当にプログラム組んでみました。

Service Bus名前空間の作成

まず、EventHubとQueueのServiceBusの名前空間を作成します。

今回はokazuki-servicebusという名前で作成しました。

f:id:okazuki:20151012220020p:plain

EventHubの作成

イベントハブ作ります。

okazuki-eventhubという名前で作りました。パーティション数とかは最小の値にしました。

f:id:okazuki:20151012220152p:plain

f:id:okazuki:20151012220159p:plain

共有アクセスポリシーをIOという名前でリッスンと送信で作ります。

f:id:okazuki:20151012222246p:plain

Queueの作成

キューを作ります。

okazuki-queueという名前で作りました。設定はよくわからんのでデフォルトで。

f:id:okazuki:20151012220434p:plain

f:id:okazuki:20151012220442p:plain

共有アクセスポリシーをIOという名前でリッスンと送信で作りました。

f:id:okazuki:20151012220556p:plain

接続文字列の取得

後でプログラムで使うので、EventHubとQueueのダッシュボードから作榮した共有アクセスポリシーに対する接続文字列を取得しておきます。

Stream Analyticsの作成

作成は適当に。

f:id:okazuki:20151012221029p:plain

入力を作ります。先ほど作ったイベントハブを使いたいのでデータストリームのイベントハブを選びます。共有アクセスポリシーもIOを選びます。

f:id:okazuki:20151012222447p:plain

あとはUTF-8のJSONを選んでおきます。

出力は、ServiceBus キューを選んで先ほど作ったQueueを選びます。共有アクセスポリシーはIOを選びます。

f:id:okazuki:20151012221508p:plain

次のページはJSONのUTF-8の改行区切りを選んで作成します。

クエリは右から左への垂れ流しです。

SELECT
    *
INTO
    [Output]
FROM
    [Input]

保存して実行しましょう。

プログラムの作成

NuGetから以下のものを参照に追加します。

  • WindowsAzure.ServiceBus
  • Newtonsoft.Json

そして、さくっとEventHubへのデータの送信とQueueからのデータの受信の処理を書きます。キーはさっき取得したやつを使います。

using Microsoft.ServiceBus.Messaging;
using Newtonsoft.Json;
using System;
using System.Text;

namespace ConsoleApplication11
{
    class Program
    {
        staticvoid Main(string[] args)
        {
            var qc = QueueClient.CreateFromConnectionString(
                "Endpoint=sb://okazuki-servicebus.servicebus.windows.net/;SharedAccessKeyName=IO;SharedAccessKey=/yXU2i/FO5ZEVsijSscJGYXi5KPBRT4m10cU7y9pgu8=",
                "okazuki-queue");
            qc.OnMessage(x =>
            {
                var receiveData = JsonConvert.DeserializeObject<Data>(x.GetBody<string>());
                Console.WriteLine(DateTime.Now - receiveData.Time);
            });

            var ec = EventHubClient.CreateFromConnectionString(
                "Endpoint=sb://okazuki-servicebus.servicebus.windows.net/;SharedAccessKeyName=Input;SharedAccessKey=xbw5s/+EMgfb05abvHMKGe/7lto9+TIWlQ4v4zKOAK4=",
                "okazuki-eventhub");
            for (int i = 0; i < 10; i++)
            {
                var data = new EventData(
                    Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Data { Time = DateTime.Now })));
                ec.Send(data);
            }

            Console.ReadKey();
        }
    }

    class Data
    {
        public DateTime Time { get; set; }
    }
}

DateTimeつっこんだデータをEventHubに渡して、Queueで受け取ったときの現在時間と比較してます。

実行結果はこんな感じになりました。

f:id:okazuki:20151012222818p:plain

まぁ、クラウドにいって色々経由してる割にはいい感じ?

UWPのコンパイル時データバインディング(x:BInd)でPropertyChanged_XXXXXがないというコンパイルエラーが出るとき

$
0
0

UWPのコンパイル時データバインディングを試してたのですが、こんなコードを書いたら表題のようなコンパイルエラーが出るようになりました。

publicsealedpartialclass MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }
}

class MainPageVM : INotifyPropertyChanged
{
    publicstring Text { get; set; } = "Hello world";

    publicevent PropertyChangedEventHandler PropertyChanged;
}
<Pagex:Class="App43.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:App43"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Page.DataContext><local:MainPageVM x:Name="ViewModel" /></Page.DataContext><Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"><TextBlock Text="{x:Bind ViewModel.Text, Mode=OneWay}" /></Grid></Page>

すると

現在のコンテキストに 'PropertyChanged_ViewModel' という名前は存在しません。

というエラーが出ます。

条件

ViewModelがINotifyPropertyChangedを実装していて、XAMLでx:Nameを使って変数宣言していて、Mode=OneTime以外を指定すると起きるっぽいです。

解決策

プロパティ化するなりフィールド化するなりしましょう。

publicsealedpartialclass MainPage : Page
{
    private MainPageVM ViewModel => this.DataContext as MainPageVM;
    public MainPage()
    {
        this.InitializeComponent();
    }
}

class MainPageVM : INotifyPropertyChanged
{
    publicstring Text { get; set; } = "Hello world";

    publicevent PropertyChangedEventHandler PropertyChanged;
}
<Pagex:Class="App43.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:App43"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Page.DataContext><local:MainPageVM /></Page.DataContext><Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"><TextBlock Text="{x:Bind ViewModel.Text, Mode=OneWay}" /></Grid></Page>

Universal Windows Platform版UWPのPrism.UWPがリリースされました

$
0
0

今朝がたPrismのUWP版がリリースされていました。

github.com

Prism.StoreAppsからちょっと進化(非互換ともいう)してたりします。 とりあえずGitHubのPrism 6自習用リポジトリをベースにちょっとずつ勉強していきたいと思います。

ということでざっとどんな便利機能があるのか列挙しておきました。これをベースに個別機能をやっていこうかな。

github.com


UWP版PrismのHello worldを書きました

UWP版Prismの画面遷移について書きました

競技プログラミングの問題をしてみた

$
0
0

chomado.com

@chomadoさんの参加したという競技プログラミングの問題を解いてみました。 たまには頭の体操。

B問題

英小文字からなる 12 個の文字列 S1, S2, …, S12 が入力されます。
これらの文字列のうち、文字 r が含まれるものの個数を数えてください。

ちょまどさんと、ほぼ一緒ですね。 データ読み込むInput関数もLINQにしてみたくらい

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        staticvoid Main(string[] args)
        {
            var count = Input()
                .Where(x => x.Contains("r"))
                .Count();
            Console.WriteLine(count);
        }

        privatestatic IEnumerable<string> Input() => Enumerable.Range(1, 12).Select(_ => Console.ReadLine());
    }
}

C問題

あなたはスーパーハッカーです。高橋君を攻撃対象に定めたあなたは、
 高橋君のパソコンのパスワードに関して次の事実を突き止めました。

長さは N 文字である。
a, b, c 以外の文字は含まれない。
 高橋君のパソコンのパスワードの候補として考えられる文字列をすべて列挙してしまいましょう。 

ちょまどさんは再帰でスッキリ解いてました。 私はLINQを使ってみました。 SelectManyを指定された回数-1回繰り返して文字列を合成していってます。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        staticvoid Main(string[] args)
        {
            var source = new[] { "a", "b", "c" }.AsEnumerable();
            Func<string, IEnumerable<string>> process = x => source.Select(y => $"{x}{y}");

            var num = int.Parse(Console.ReadLine());
            var result = source;
            foreach (var _ in Enumerable.Range(1, num - 1))
            {
                result = result.SelectMany(process);
            }

            foreach (var item in result)
            {
                Console.WriteLine(item);
            }
        }
    }
}

D問題

高橋君は 1 以上 N 以下のすべての整数を十進表記で一回ずつ紙に書きました。
この作業で、高橋君は 1 という数字を何個書いたでしょうか。
using System;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        staticvoid Main(string[] args)
        {
            var num = int.Parse(Console.ReadLine());
            var count = Enumerable.Range(1, num)
                .SelectMany(x => x.ToString().ToCharArray())
                .Count(x => x == '1');
            Console.WriteLine(count);
        }
    }
}

アルゴリズム的にはちょまどさんと同じなので20点になりそうだ…。 100点ってどんなのなんだろう。

と思ってみてみると難しい…。

abc029.contest.atcoder.jp

UWP版PrismのDeviceGestureServiceについて書いてみました

$
0
0

github.com

Prism.StoreAppsのころには無かったDeviceGestureServiceについて書いてみました。 あると便利な奴です。

ブログを独自ドメインにしました

UWP版PrismのMVVM関連クラスについて書きました

$
0
0

基本的には前書いたやつ見てねってスタンスだけど、ValidatableBindableBaseクラスだけは新顔なので書いたよ。

github.com

UWPのImageのSourceにnullや空文字をx:Bindしたときの対処方法(対処できない)

$
0
0

UWP の x:Bind で ImageSource を指定すると null や string.Empty のときにエラーが発生する | 雪猫ノート

間にConverterが入るケースだとnullとか渡すとエラーになっちゃうんですよね…そのままnull返してくれればいいものを。 ということで、ViewModel側でImageSourceを持つようにしないといけないです。

using System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

namespace App47
{
    publicsealedpartialclass MainPage : Page
    {
        private MainPageViewModel ViewModel { get; } = new MainPageViewModel();

        public MainPage()
        {
            this.InitializeComponent();
        }
    }

    class MainPageViewModel
    {
        public ImageSource NullImage { get; set; }
    }
}

こんな感じのVMを定義しておいて、以下のようなXAMLを定義すると型変換が入らないのでエラーが出なくなります。解せぬ動きですね…。

<Page x:Class="App47.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:App47"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"><Image Source="{x:Bind ViewModel.NullImage}" /></Grid></Page>

ちなみにnullのときに表示したい値はTargetNullValueで設定できます。こんな感じに

<Page x:Class="App47.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:App47"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"><Image Source="{x:Bind ViewModel.NullImage, TargetNullValue=ms-appx:///Assets/StoreLogo.png}" /></Grid></Page>

とここで思いついたのですが

FallbackValueというプロパティがx:Bindにあるのを思い出しました。

結論からいうとこれを指定してもダメでした。自動生成されたソースを読むとPageやViewModelがnullのときに使用されるらしい…。今回の用途向けじゃないのね…。

まとめ

VとVMで型を合わせておくのが無難っぽいです。もしくは、nullが入らないように制御するか。


英語圏のPCLライブラリを日本語環境のUWPで使うとエラーで落ちるかもしれない… #windev_jp

$
0
0

Prism.UnityのUWP版を使ってリリースビルドすると、アプリ起動時に落ちるので何だろうと数日探ったところ以下の条件がそろったときに例外が発生することがわかりました。

  • 設定 → 時刻と言語 → 地域と言語の言語にEnglishが追加されていない(デフォルトそうだよね??)
  • PCLのライブラリのAssemblyInfoにNeutralResourcesLanguage("en")が設定されている(英語圏の環境で作るとこうなるっぽい)
  • PCLのライブラリでリソースを作ってるが特に多言語化はされていない(普通にリソース作っただけ)
  • UWPの言語設定がja-JPになっている
  • UWPからPCLで定義されたリソースに間接的にでもアクセスする

因みに発生する例外はNullReferenceExceptionってなるときもあればArgumentNullExceptionになることもあるかな。どういう条件のときにNullReferenceExceptionで、どういう条件のときにArgumentNullExceptionなのかは追い切れてません。

再現プロジェクト

GitHubに再現するプロジェクトおいてみました。

github.com

上記リポジトリをCloneしてHelloWorldAppをスタートアッププロジェクトにしてReleaseのx86にして実行すると落ちるはずです。(OSの言語の設定にEnglishを入れると落ちなくなる)

これ仕様なのかしら…。

RxとReactivePropertyを使って、WPFでUnidirection Data Flowを実現するを真似してみた

$
0
0

ありがたいことに最近ReactivePropertyを勧めたら使い始めて頂けました。

qiita.com

このコードを大げさに書いたらどうなるかなぁというのでやってみました。 ということでModel部分。

なんかきっかけがあるタイミングで、インクリメントし続けるだけの奴。

class CounterProvider
{
    public IObservable<int> ObservableCounter { get; }

    public CounterProvider(IObservable<Unit> countupTrigger)
    {
        this.ObservableCounter = countupTrigger
            .Scan(0, (x, _) => x + 1);
    }
}

コマンドとReactiveProperty持った人。

class MainWindowViewModel
{
    public ReadOnlyReactiveProperty<int> Count { get; }
    public ReactiveCommand IncrmentCommand { get; }

    public MainWindowViewModel()
    {
        this.IncrmentCommand = new ReactiveCommand();
        var model = new CounterProvider(this.IncrmentCommand.ToUnit());
        this.Count = model.ObservableCounter
            .ToReadOnlyReactiveProperty();
    }
}

んで画面。

<Window x:Class="StreamApp.MainWindow"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"xmlns:local="clr-namespace:StreamApp"mc:Ignorable="d"Title="MainWindow"Height="350"Width="525"><Window.DataContext><local:MainWindowViewModel /></Window.DataContext><StackPanel><Button Content="Count"Command="{Binding IncrmentCommand}"/><TextBlock Text="{Binding Count.Value}" /></StackPanel></Window>

仰々しくやるならこんなイメージかな?どうだろう。 とりあえず、全部IOでつなぐようにしてみた。

UWPで複数ウィンドウを出す

$
0
0

UWPで複数ウィンドウの出し方です。 基本的には、CoreApplicationのCreateNewViewで新しいCoreApplicationViewを作って、そいつのDispatcher上で新しいWindowを表示してやるようなイメージです。コードでいうとこんな感じ。

private async void button_Click(object sender, RoutedEventArgs e)
{
    var currentViewId = ApplicationView.GetForCurrentView().Id;
    await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
    {
        Window.Current.Content = new Frame();
        ((Frame)Window.Current.Content).Navigate(typeof(NewWindowPage));
        Window.Current.Activate();
        await ApplicationViewSwitcher.TryShowAsStandaloneAsync(
            ApplicationView.GetApplicationViewIdForWindow(Window.Current.CoreWindow),
            ViewSizePreference.Default,
            currentViewId,
            ViewSizePreference.Default);
    });
}

複数ウィンドウを出したときに気を付けないといけないのは、それぞれのウィンドウが別のスレッドで動いているということです。 何か値の共有をするときは、最終的なPropertyChangedやCollectionChangedのイベントの発火を各ウィンドウのUIスレッド上でやらないといけません。 サンプルでは、ReactivePropertyを使ってスレッドを切り替えています。

github.com

f:id:okazuki:20151023220301p:plain

複数のプロパティを監視してReactivePropertyの値を更新する

$
0
0

こういう場合は2つのIObservableをCombineLatestで合成してからReactivePropertyにしてしまえばお手軽です。

using Reactive.Bindings;
using System.Reactive.Linq;

namespace MultiValueApp
{
    class MainWindowViewModel
    {
        public ReactiveProperty<int> Lhs { get; }
        public ReactiveProperty<int> Rhs { get; }
        public ReadOnlyReactiveProperty<int> Answer { get; }

        public MainWindowViewModel()
        {
            this.Lhs = new ReactiveProperty<int>(0);
            this.Rhs = new ReactiveProperty<int>(0);
            this.Answer = this.Lhs.CombineLatest(this.Rhs, (x, y) => x + y)
                .ToReadOnlyReactiveProperty();
        }
    }
}

この例では、監視元はReactivePropertyですが通常のINotifyPropertyChangedを実装したクラスはObservePropertyでIObservable化できるので、そいつをCombineLatestしてやればOKです。

UWP版Prismのv6.0.1が出ました

$
0
0

github.com

個人的にはお願いしたIssueの意を組み込んでくれたリリースなのでうれしい。

Viewing all 1388 articles
Browse latest View live