「何番煎じだよ( ˇωˇ )」と言われそうですが、自分で前々からやってみたかったことです。

effectを使って、ボタンコントロールにボーダーラインを引いてみます。

Effectとは?

りんちゃんりんちゃん

Effectとは、Xamarin.Formのコントロールのプロパティとしては提供されていないが、ネイティブのコントロールをいじることができる機能だにゃ~。どういう感じで使えるのかを見てみるにゃ~。

ラベルコントロールにボーダーラインを引いてみる

りんちゃんりんちゃん

ラベルコントロールにはBorderプロパティが無いのにゃ~。とりあえず、ラベルコントロールにテキストだけ設定した場合にどう見えるかを確認してみるのにゃ~。


Windows8.1AndroidiPhone
りんちゃんりんちゃん

当然ながら、境界線が全く分からないのにゃ~。

方法①:ボタンコントロールをFrameで囲う

りんちゃんりんちゃん

FrameにはOutlineColorプロパティがあり、これを使えば上手くいきそうだにゃ~。


Windows8.1AndroidiPhone
りんちゃんりんちゃん

Androidには色が適用されてにゃいが、OutlineColorプロパティ自体はそれぞれに効いてるみたいだにゃ~。

かりまたかりまた

あれ、Frame使えば一件落着じゃね??

りんちゃんりんちゃん

そんな事言わないのにゃ~。AndroidiPhoneでは勝手に影が付いているのにゃ~。これが気に食わない(ということにしとく)のにゃ~。

方法②:ボタンコントロールの背景を透明にしてみる

りんちゃんりんちゃん

ボタンコントロールにはBorderColorプロパティがあるのにゃ~。ただ、ボタンをそのまま置くとボタンを置いてる!とすぐに分かってしまうのにゃ~。そこで、ボタンの背景を透明にしてみるのにゃ~。


Windows8.1AndroidiPhone
かりまたかりまた

背景を透明にすればイケる!そう思っていた時期がボクにもありました。

りんちゃんりんちゃん

ボタン感満載だにゃ~。

方法③:Effectを使用してみる

りんちゃんりんちゃん

さてさて、漸く本命がきたのにゃ~。Effectはそれぞれのプロジェクトに記述が必要になるのにゃ~。

りんちゃんりんちゃん

AndroidUnderlineEffectクラスを追加するにゃ~。

りんちゃんりんちゃん

UnderlineEffectクラスの中身は以下のようにするのにゃ~。


りんちゃんりんちゃん

iOSにも同じようにUnderlineEffectクラスを作成してみるのにゃ~。


りんちゃんりんちゃん

最後に、PCLにも同様にしてUnderlineEffectクラスを作成するのにゃ~。


りんちゃんりんちゃん

さて、準備が整った所でEffectを使ってみるのにゃ~。


iPhoneAndroid
かりまたかりまた

さて、お気付きだろうか。タイトルが「枠線を付ける」にも関わらず、UnderlineEffectだったり、そもそもこれ枠線じゃなくて下線じゃね?


かりまたかりまた

Androidで枠線を付ける方法が意外と難しかったので、下線を付ける方法で妥協しましたすみません。

Effectを使うにあたって色々と補足

Effect内の属性について

かりまたかりまた

用語の説明からしましょう。まず、Effectを使いたいプラットフォームでそれぞれUnderlineEffect.csを追加しました。この中に

  • [assembly: ResolutionGroupName(“App6”)]
  • [assembly: ExportEffect(typeof(App6.iOS.UnderlineEffect), “UnderlineEffect”)]

というような記述があります。

ResolutionGroupName属性
ExportEffect属性
かりまたかりまた

上記のコード内にさらっとApp6とか書いていますが、これは私が使用しているプロジェクトのアセンブリ名がApp6なのでこう書いています。自分で作成しているプロジェクトのアセンブリ名に適宜変更してください。

Effect内のメソッドについて

かりまたかりまた

次に、メソッドについてです。UnderlineEffect.csではPlatformEffectを継承してエフェクトを使用できるようにしています。このクラスを継承するには次の2つのメソッドを用意する必要があります。

OnAttachedメソッド
OnDetachedメソッド
かりまたかりまた

字面だけだと分かりにくいかもしれませんが、Effectを使用する際に<Label.Effects></Label.Effects>タグで囲んでいます。このようにしてEffectプロパティにエフェクトを割り当てる際にはOnAttachedメソッドが走っています。

Effect内のコントロールのキャストについて

かりまたかりまた

それぞれのUnderlineEffect.cs内ではコントロールを適宜、それぞれのプラットフォームで使用されている型に変換されています。例えば、AndroidではコントロールをTextView型にキャストしており、iOSではUILabel型にキャストしています。

かりまたかりまた

どういう事か?と言いますと、Xamarinではこういった各プラットフォームで宣言されている異なる型のクラスをラップした形で提供しています。つまりXamarin.FormsLabelコントロールに相当するものがAndroidではTextViewコントロールiOSではUILabelコントロールに対応しているという訳です。

なんだとさんなんだとさん

なん…だと…

かりまたかりまた

なので、これらのキャストの意味合いとしては、「それぞれのプラットフォーム上でXamarin.FormsLabelに相当するコントロールが配置されていたらキャストを行う」という処理を行っています。

まとめ

りんちゃんりんちゃん

Effectを扱う事でプラットフォーム毎に処理を分ける事ができたり、Xamarin上だけではなくてネイティブの力を借りて表現をすることも出来るということがわかったにゃ~。

りんちゃんりんちゃん

ただし、それにはそれぞれのプラットフォームでの書き方も知る必要も当然出てくるのにゃ~。自由度が上がる分、実装コストが若干上がってしまう事もわかったのにゃ~。