問題
UWPのTextBoxは、一行のものしか扱えず、複数行のものはRichEditBoxをつかうみたいのだけど、とてもMVVM的に使いずらいものになっている。RichEditBox自体が機能的に高度なので、仕方いない面もある。RichEditBoxは、文字に色を付けたりフォントを変えたり画像を挿入できたりいろいろできる。
しかし、やりたいことは、ただ複数行の入力をしてそれを受け取りたいだけで、WPFのTextBoxでできたことをただやりたいだけである。
そのために、RichEditBoxを継承で対応する。MVVM的に使いやすくするには、継承が一番いいと思う。
コード
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace MyUwpLib.Controls
{
public class RichEditEx:RichEditBox
{
public RichEditEx()
: base()
{
this.TextChanged += RichEditEx_TextChanged;
}
private void RichEditEx_TextChanged(object sender, RoutedEventArgs e)
{
var t =GetText();
if (t != Text)
{
Text = t;
}
}
public TextGetOptions TextGetOption { get; set; } = TextGetOptions.None;
public TextSetOptions TextSetOption { get; set; } = TextSetOptions.None;
string GetText()
{
string t;
this.Document.GetText(TextGetOption, out t);
return t;
}
void SetText(string text)
{
if(GetText()!= text)
{
this.Document.SetText(TextSetOption, text);
}
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
// Using a DependencyProperty as the backing store for TextProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(RichEditEx), new PropertyMetadata(string.Empty, callback));
private static void callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var reb = (RichEditEx)d;
reb.SetText((string)e.NewValue);
}
}
}
使い方
XAMLでのかきかた。
<myContorl:RichEditEx Text="{Binding TextData,Mode=TwoWay}"></myContorl:RichEditEx>
おわりに
これは、テキストを表示し、その入力を得るということのみをしている。RichEditBox本来の高機能を使い切っているとは言えない。文字の色を適切に変えてごにょごにょということはできない。
テキストの更新のたびにチェックしている挙動がなんか気持ち悪い。テキストが巨大になると重そう。いい書き方がわかりませぬ。