データバインディングPOCOプロパティ
-
03-07-2019 - |
質問
INotifyPropertyChanged
と INotifyCollectionChanged
を実装する任意の2つのCLRプロパティ間のバインディングを可能にするデータバインディングフレームワーク(BCLまたはその他)がありますか?次のようなことができるはずです:
var binding = new Binding();
binding.Source = someSourceObject;
binding.SourcePath = "Customer.Name";
binding.Target = someTargetObject;
binding.TargetPath = "Client.Name";
BindingManager.Bind(binding);
someSourceObject
と someTargetObject
は、 INotifyPropertyChanged
を実装する単なるPOCOです。ただし、これに対するBCLのサポートについては知りません。これを許可する既存のフレームワークがあるかどうかはわかりません。
更新:利用可能な既存のライブラリがないことを考えると、私は自分自身でそれを書きました。 こちらで利用可能です。
ありがとう
解決
ボイドを埋めるために Truss を作成しました。
他のヒント
これを行うライブラリはありませんが、独自のライブラリをかなり簡単に作成できます。
ここに、2つの単純なプロパティ間の双方向のデータバインディングを確立するために、数分でノックアップした基礎を示します。
public static class Binder
{
public static void Bind(
INotifyPropertyChanged source,
string sourcePropertyName,
INotifyPropertyChanged target,
string targetPropertyName)
{
var sourceProperty
= source.GetType().GetProperty(sourcePropertyName);
var targetProperty
= target.GetType().GetProperty(targetPropertyName);
source.PropertyChanged +=
(s, a) =>
{
var sourceValue = sourceProperty.GetValue(source, null);
var targetValue = targetProperty.GetValue(target, null);
if (!Object.Equals(sourceValue, targetValue))
{
targetProperty.SetValue(target, sourceValue, null);
}
};
target.PropertyChanged +=
(s, a) =>
{
var sourceValue = sourceProperty.GetValue(source, null);
var targetValue = targetProperty.GetValue(target, null);
if (!Object.Equals(sourceValue, targetValue))
{
sourceProperty.SetValue(source, targetValue, null);
}
};
}
}
もちろん、このコードにはいくつかの機能が欠けています。追加するものには
が含まれます-
source
およびtarget
が割り当てられていることの確認 -
sourcePropertyName
およびtargetPropertyName
で識別されるプロパティが存在することの確認 - 2つのプロパティ間の型の互換性の確認
また、Reflectionは比較的低速です(破棄する前にベンチマークを行いますが、それは遅くありません)。そのため、代わりにコンパイル済みの式を使用することをお勧めします。
最後に、文字列でプロパティを指定するとエラーが発生しやすいことを考えると、代わりにLinq式と拡張メソッドを使用できます。次に、書く代わりに
Binder.Bind( source, "Name", target, "Name")
書くことができます
source.Bind( Name => target.Name);
AutoMapper は2つのインスタンス間で値をコピーできますが、これを行うには独自のコードを記述する必要があります自動的に発生します。
多分バインド可能なLINQ または連続linq が役立ちます。実際に「派生プロパティ」であるモデルプロパティを追加しようとしている場合UIのバインドを容易にするために、実際の更新データのこれら2つのフレームワークが役立ちます。
小さなバインドプロジェクトを作成しました。neastedプロパティ間のバインドを完全にサポートし、バインドアクションを非同期にします。シンタックスはこれ以上簡単ではありません:
//Two way binding between neasted properties:
Bind.TwoWay(()=> client.Area.Data.Name == this.AreaName);
//On change action execute:
Bind
.OnChange(()=> client.Personal.Name)
.Do(x => clientName = x);
プロパティを DependencyProperty として定義した場合あなたはそれをすることができます。 WFとWPFの両方に実装があります(最初のリンクはWPF用です。WFの場合は this one)ので、どちらを使用するかを決定する必要がありますが、どちらも必要に応じて十分です。