Мне не известна какая-либо библиотека , которая делает это, но вы можете написать свою собственную довольно легко.
Вот база, которую я обнаружил за несколько минут, которая устанавливает двухстороннюю привязку данных между двумя простыми свойствами:
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
- Проверка совместимости типов между двумя свойствами
Кроме того, Reflection относительно медленный (хотя тестируйте его перед тем, как выбросить, он не , а медленный), поэтому вы можете использовать вместо этого скомпилированные выражения.
Наконец, учитывая, что указание свойств в виде строки может привести к ошибкам, вы можете использовать вместо них выражения Linq и методы расширения. Тогда вместо написания
Binder.Bind( source, "Name", target, "Name")
вы могли бы написать
source.Bind( Name => target.Name);