やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Raspbian stretch MonoDevelop Eto.Forms XAML TextBox でデータ・バインディングしてみる(INotifyPropertyChanged)

 同一型のUI同士でならバインディングできた。が、こんな用途はないだろう。もっと実際のユースケースに沿った実例が欲しい。探しても見つからない。

成果物

対象環境

前回

手順

  1. プロジェクト作成
  2. TextBox追加
  3. 実行

1. プロジェクト作成

  1. メニュー→ファイル新しいソリューション
    f:id:ytyaru:20181201194454p:plain
  2. マルチプラットフォームアプリEto Application f:id:ytyaru:20181202083840p:plain
  3. 名前などを適当に入力し、Xamlを選択する
    f:id:ytyaru:20181202083922p:plain
    f:id:ytyaru:20181202083950p:plain
  4. 場所を入力する
    f:id:ytyaru:20181201194509p:plain
  5. プロジェクトが作成される
    f:id:ytyaru:20181202084143p:plain

2. TextBox追加

  1. Xamlファイルを開く(MainForm.xeto)
  2. <TextBox x:Name="textBox1" Text="https://www.google.co.jp" Width="800" KeyDown="HandleInputUrl" />を追記する
  3. csファイルを開く(MainForm.xeto.cs)
  4. HandleInputUrlメソッドを追加する

ソースコード抜粋

MainForm.xeto

 空っぽにする。データバインディングC#でしか実装できないので、それに引きづられてすべてC#で実装することになる。XAMLとは一体……。MVVMとは一体……。全然M,V,Cが分離できてなくね?

<?xml version="1.0" encoding="UTF-8"?>
<Form xmlns="http://schema.picoe.ca/eto.forms" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="My Eto Form" ClientSize="400, 350" Padding="10">
    <StackLayout>
    </StackLayout>
</Form>
``````

#### UrlModel.cs

 TextBoxのモデルクラスを作る。これが問題の`INotifyPropertyChanged`を継承した超面倒なやつ。

using System; using System.ComponentModel; // INotifyPropertyChanged using System.Runtime.CompilerServices; // CallerMemberName

namespace HelloXamlBinding { public class UrlModel : INotifyPropertyChanged { string url; public string Url { get { return url; } set { this.url = value; OnPropertyChanged(); } }
void OnPropertyChanged([CallerMemberName] string memberName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(memberName)); } public event PropertyChangedEventHandler PropertyChanged; } }

 たかが文字列ひとつでこのコード量。本質的でない内容。これイベント駆動式よりひどくないか?

#### MainForm.xeto.cs

 XAMLで追加した`HandleInputUrl`メソッドを実装する。

using System; using System.Collections.Generic; using Eto.Forms; using Eto.Drawing; using Eto.Serialization.Xaml;

namespace HelloXamlBinding { public class MainForm : Form { public MainForm() { XamlReader.Load(this); Create(); } private void Create() { var textBox = new TextBox(); textBox.TextBinding.BindDataContext((UrlModel m) => m.Url); Content = textBox; var model = new UrlModel { Url = "https://www.yahoo.co.jp" }; DataContext = model; } } }

 TextBoxの生成、バインディング、Windowへの追加。単に初期値を設定するだけなので、わざわざデータ・バインディングを使うメリットもないコード。

## 3. 実行

1. Ctrl+F5で実行
1. 怒られた  
[f:id:ytyaru:20181202084218p:plain]  
1. ファイルパスを辿ってexeファイルを直接叩くと実行できた  
[f:id:ytyaru:20181204080023p:plain]

# 所感

 これをWebViewと連動させて、入力したURLを表示させたい。そのためには、KeyDownイベントとWebViewへの値セットが必要。次回以降、順にやってみる。