のんのんびりびりプログラマー

のんびりプログラム関係を書いています。また日々思った事を思った時に。

【WPF小技集】MVVMLightのMessengerの使い方

Messengerを使えばViewModelからViewに通知を送って
処理をさせることを簡単にできます。

例えばポップアップを出したいや、
新しい画面を開きたいなど

WPFでは画面の処理はあくまでViewで行うような思考ですので、
ViewModelからMessengerでViewに通知を送ります。

ChatViewModel.cs

public void SendCommandRun()
{
    ChatMessage chatMessage = new ChatMessage(true, this.InputMessage);
    this.ChatMessageList.Add(chatMessage);

    Messenger.Default.Send(chatMessage, "MyMessage");

    this.InputMessage = "";
}

ChatView.xaml.cs

public ChatView()
{
    InitializeComponent();

    Messenger.Default.Register<ChatMessage>(this, "MyMessage", Test);
}

private void Test(ChatMessage cm)
{
    //ここに処理を書く
}

ViewModelにはこれを書きます。
第一引数:ViewModel側に投げたいインスタンス
第二引数:Tokenと呼ばれ同じ他のMessengerと区別するもの
     これはintでもstringでも何でもOK

Messenger.Default.Send(chatMessage, "MyMessage");

Model側にはこれを書きます。
ChatMessage:これはどのクラスを投げてきているか明示するもの
第一引数のthis:これはお決まり
第二引数:Tokenで投げたTokenと同じものを書く
第三引数:どのActionを実行するか書く
     ここでは下にPrivateでTestメソッドを記載しているので、
     Testメソッドを実行するということになる

Messenger.Default.Register<ChatMessage>(this, "MyMessage", Test);

これで簡単にMessengerを使って処理が書けます。

【WPF小技集】MVVMLightのRelayCommandの使い方

今回はMVVMLightのライブラリをNugetから落として
RelayCommandを使い方です。

まずはView側にCommandを書きます。
RelayCommandはViewModelに書きます。

ChatView.xaml

<DockPanel LastChildFill="True"
           DockPanel.Dock="Bottom">
    <Button Content="Send"
        DockPanel.Dock="Right"
        Width="50"
        Command="{Binding SendCommand}"/>
    <TextBox Text="{Binding InputMessage, Mode=TwoWay}"/>
</DockPanel>

ChatViewModel.cs

private RelayCommand _sendCommand;
public RelayCommand SendCommand
{
    get { return _sendCommand = _sendCommand ?? new RelayCommand(SendCommandRun); }
}

public void SendCommandRun()
{
    //ここにややりたい処理を記載
}

そのままではエラーになりますので、

using GalaSoft.MvvmLight.CommandWpf;

を追加してください。

これでボタンを押すとこの"SendCommandRun"のメソッドが実行されるようになります。

【WPF小技集】Windowの画面サイズのBinding方法

WindowサイズをBindingしようとするとまず陥ってしまいます。

たぶんこんな感じに普通に書いているんじゃないでしょうか。

ChatView.xaml

<Window x:Class="ChatBot.View.ChatView"
        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:ChatBot.View"
        mc:Ignorable="d"
        Height="{Binding Path=Size.WindowHeight}"
        Width="{Binding Path=Size.WindowWidth}"
        Title="ChatView">

正しくBindingしていますが、
デバッグをすると反映されない。

Mode=TwoWay

が抜けているんです。

<Window x:Class="ChatBot.View.ChatView"
        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:ChatBot.View"
        mc:Ignorable="d"
        Height="{Binding Path=Size.WindowHeight, Mode=TwoWay}"
        Width="{Binding Path=Size.WindowWidth, Mode=TwoWay}"
        Title="ChatView">
Mode=TwoWay

View→ViewModel、ViewModel→Viewの双方向でBindingをすると
明示的に書くことになります。

Modeは
"Default"、"OneTime"、"OneWay"、"OneWayToSource"、"TwoWay"
があります。

OneTime :ViewModel→Viewに一度だけ一方向にBinding
OneWay :ViewModel→Viewの一方向にBinding
OneWayToSource:View→ViewModelの一方向にBinding
TwoWay :ViewModel→View、View→ViewModelの双方向でBinding

どのModeを選ぶからその時々で考えてください。
基本的にTwoWayであればBindingします。

【WPF小技集】一覧

【WPF小技集】起動時のスタートメソッドの設定 - のんのんびりびりプログラマー
【WPF小技集】Windowの画面サイズのBinding方法 - のんのんびりびりプログラマー
【WPF小技集】MVVMLightのRelayCommandの使い方 - のんのんびりびりプログラマー
【WPF小技集】MVVMLightのMessengerの使い方 - のんのんびりびりプログラマー

オブジェクト指向は難しい

私はJavaを使っていました。
現在はc#をメインに使っています。

Javaからc#への移行はあまり難しくはなかったです。
それは両方とも比較的書き方が似ているからです。

そして何よりも両方ともオブジェクト指向
元に考え作られた言語だからです。

ではオブジェクト指向とは何か?

難しいですよね。

オブジェクト指向は。

オブジェクト指向を説明できる人は
なかなかいないと思います。
私もまだまだオブジェクト指向
勉強途中であります。

簡単に言うとオブジェクト指向
プログラミングをパソコン的に考えるのではなく、
人間が使いやすいように
物として扱うと言うことです。

物?

人間も犬も猫も机も椅子も

全て物です。

だからこそ全てオブジェクトになるんです。
私たちが認識しているものは全てオブジェクトなんです。

《継承》
具体的なクラスは一般的なクラスの性質を引き継ぐ。
犬や猫の例で見てみましょう。
一般的なクラスは動物
具体的なクラスは犬、猫
犬も猫も動物であります。
だから両方とも鳴きますよね。
犬ならわんわん。
猫ならにゃーにゃー。
動物クラスには鳴くと言うメソッドがあります。
その動物クラスを継承して
犬、猫はそれぞれの鳴き方をします。

カプセル化
何をやるかはブラックボックスで与えた値に対して、ある計算をして返却させることです。
例えば掛け算のクラスがあるとします。
そこに2つの数を渡すとそれを掛けた値を返却してくれます。
呼び出す方は掛けた値を返却してくれればいいだけです。
中のロジックがどうなってるかは関係ありません。
ただ返却値が合っていればいいんです。
だから5と3が引数の場合は
「5*3」でも「5+5+5」でもどっちでもいいんです。
返却値が正しければ。

ポリモーフィズム
どんな場合でも同じ動作をする事。ただし、その呼び出し元により異なる。
例えば、遊園地の入場料を知りたい場合があります。
子供は300円。
大人は500円。
高齢者は400円。
子供が僕の入場料は?とメソッドを呼び出せば300円が表示されます。
大人が呼び出せば500円。
高齢者が呼び出せば400円。
同じメソッド名であるにもかかわらず、
呼び出す人が変わる事で
表示させる金額が異なる事をいいます。

簡単に書きましたが、
オブジェクト指向の本質は
簡単です。
難しく考えるのではなく、
頭を柔らかくして柔軟に考えましょう。
いたってシンプル。
シンプルだからわかりにくい。

実際のプログラミングに落とし込む場合は
設計が重要になり、
これはオブジェクト指向には向いてないな
と思う事があるかと思います。

全ての物はオブジェクトですから
全てオブジェクト指向で書く事ができます。

是非とも仕事、プライベートで
プログラミングをする時になったら
思い出してみてください。

【WPF小技集】起動時のスタートメソッドの設定

WPFプロジェクトで起動時にメソッドを実行させたい場合は
下記のように書きます。

App.xaml

<Application x:Class="ChatBot.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:ChatBot"
             Startup="StartUp_Application">
    <Application.Resources>
         
    </Application.Resources>
</Application>


あまり変わっていないように思えますが、

Startup="StartUp_Application"


が変わっています。

"StartupUri"から"Startup"に変更します。

そして

App.xaml.cs

public partial class App : Application
{
    public void StartUp_Application(object sender, StartupEventArgs e)
    {
        ChatViewModel chatViewModel = new ChatViewModel();

        ChatView chatView = new ChatView()
        {
            DataContext = chatViewModel
        };

        chatView.Show();
    }
}


そして"StartUp_Applicationメソッドの引数の"e"には
コマンドライン引数が入ります。

ChatBotのAI化に向けてLUISを使ってみる④

いよいよLUISをBotApplicationに追加してみます。

 

前のブログでLUISのアカウント作成、IntentsとEntitiesの登録、テストを書いています。

 

まだの方は下記を参考にしてください。

【LUISアカウント作成】

ChatBotのAI化に向けてLUISを使ってみる① - のんのんびりびりプログラマー

【IntensとEntitiesの登録】

ChatBotのAI化に向けてLUISを使ってみる② - のんのんびりびりプログラマー

【テスト】

ChatBotのAI化に向けてLUISを使ってみる③ - のんのんびりびりプログラマー

 

 

では公開してツールに移植していきます。

 

【Publish App】を選択して

【Endpoint Key】と【Endpoint slot】を選択して【Publish】をクリック

 

f:id:shiganaise:20170717022554p:plain

 

これでAPIが完成です。

赤枠【Endpoint url】にURLが出ます。

 

f:id:shiganaise:20170717022740p:plain

 

こんな感じでURLが出てきます。

この【q=】の後に文章を送るとJSON形式でIntentsとEntitiesが返却されます。

https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/XXXX&timezoneOffset=540&q=

 

アプリに入れる前にブラウザで試してみます。

【q=東京から新大阪まで新幹線で】

でやってみると下記が返って来ました。

 

{
  "query": "東京から新大阪まで新幹線で",
  "topScoringIntent": {
    "intent": "到着時間計測",
    "score": 1.0
  },
  "intents": [
    {
      "intent": "到着時間計測",
      "score": 1.0
    },
    {
      "intent": "None",
      "score": 0.0132731646
    }
  ],
  "entities": [
    {
      "entity": "新幹線",
      "type": "交通手段",
      "startIndex": 9,
      "endIndex": 11,
      "score": 0.9684145
    },
    {
      "entity": "新 大阪",
      "type": "到着点",
      "startIndex": 4,
      "endIndex": 6,
      "score": 0.346304983
    },
    {
      "entity": "東京",
      "type": "出発点",
      "startIndex": 0,
      "endIndex": 1,
      "score": 0.9234941
    }
  ]
}

想定通りのJSONで返ってきました。

ではVisualStudio2017に埋め込みましょう。

埋め込む場所はRootDialogのMessageReceivedAsyncメソッドの中です。
BotFrameworkを使っています。

LUISのURLはプロパティ値とします。
string.Formatをしやすいように"{0}"を付けておきます。

そしてMessageReceivedAsyncメソッド内で
画面から入力されたメッセージを取得して
string.Formatして"q="の後にくっつけます。

そしてWebClientのDownloadStringメソッドを使用します。
ここでひとつ注意ですが、
返却のJSONに日本語が含まれていると文字化けするので、
必ずEncodingしましょう。

取得したresponseをPostAsyncすれば画面に表示されます。

f:id:shiganaise:20170717145405p:plain

ではデバッグで試してみます。
デバッグしてエミュレータを起動して
【東京から大阪に飛行機で行く】
を入力して【Enter】を押します。

f:id:shiganaise:20170717145824p:plain

 

f:id:shiganaise:20170717145934p:plain

 

想定通りにJSONが取得できました。

裏での【response】はどうなっているかと言うと

 

f:id:shiganaise:20170717150121p:plain

 

こちらも正しく取得できています。

 

あとはJSONを加工したり、

どのIntentsの場合、どのEntitiesの場合はで

ロジックを変更するかです。

 

 

下記はVisualStudio2017でのBotFrameworkのインストールと使い方のリンクです。

*************************************************************************************************

【ダウンロード編】

Visual Studio2017でBot Frameworkをやってみる① - のんのんびりびりプログラマー

【ダウンロード編】

Visual Studio2017でBot Frameworkをやってみる② - のんのんびりびりプログラマー

【起動編】

Visual Studio2017でBot Frameworkをやってみる③ - のんのんびりびりプログラマー