私はBehaviorを使用して、TextBoxをそのバウンドプロパティの検証属性(存在する場合)に接続しました。動作は次のようになります。
/// <summary>
/// Set the maximum length of a TextBox based on any StringLength attribute of the bound property
/// </summary>
public class RestrictStringInputBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
AssociatedObject.Loaded += (sender, args) => setMaxLength();
base.OnAttached();
}
private void setMaxLength()
{
object context = AssociatedObject.DataContext;
BindingExpression binding = AssociatedObject.GetBindingExpression(TextBox.TextProperty);
if (context != null && binding != null)
{
PropertyInfo prop = context.GetType().GetProperty(binding.ParentBinding.Path.Path);
if (prop != null)
{
var att = prop.GetCustomAttributes(typeof(StringLengthAttribute), true).FirstOrDefault() as StringLengthAttribute;
if (att != null)
{
AssociatedObject.MaxLength = att.MaximumLength;
}
}
}
}
}
あなたが見ることができ、動作は単純にテキストボックスのデータコンテキストを取得し、「テキスト」のためのそのバインディング式。次に、リフレクションを使用して "StringLength"属性を取得します。使用法は、このようなものです:
<UserControl
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<TextBox Text="{Binding SomeProperty}">
<i:Interaction.Behaviors>
<local:RestrictStringInputBehavior />
</i:Interaction.Behaviors>
</TextBox>
</UserControl>
またTextBox
を拡張することによって、この機能を追加することもできますが、彼らはモジュール化されたので、私は行動を使って好きです。
はい、私はそれについて考えましたが、私は本当に自分のメタデータを反映した追加のプロパティを追加し、すべてのxamlを通過し、それらのプロパティにバインドすることを避けたいと思っていました。 「カバーする」方法のタイプ...おそらく付随する行動によって? – michael
"SomeProperty"を文字列値とmaxlength値を含むオブジェクトに変更して、それぞれのプロパティにバインドすることができます。この方法では、新しいプロパティを作成する必要はありませんが、xamlの変更を行う必要があります。 – evasilchenko