Вопрос

Существуют ли какие-либо структуры привязки данных (BCL или другие), которые позволяют привязку между любые два свойства CLR которые реализуют INotifyPropertyChanged и INotifyCollectionChanged?Кажется, можно сделать что-то вроде этого:

var binding = new Binding();
binding.Source = someSourceObject;
binding.SourcePath = "Customer.Name";
binding.Target = someTargetObject;
binding.TargetPath = "Client.Name";
BindingManager.Bind(binding);

Где someSourceObject и someTargetObject это просто POCO, которые реализуют INotifyPropertyChanged.Однако мне неизвестно о какой-либо поддержке BCL для этого, и я не уверен, существуют ли существующие структуры, которые позволяют это.

ОБНОВЛЯТЬ:Учитывая, что существующей библиотеки нет, я взял на себя задачу написать свою собственную.Это доступно здесь.

Спасибо

Это было полезно?

Решение

Я написал ферма чтобы заполнить пустоту.

Другие советы

Я не знаю ни одного библиотека это делает это - но вы можете довольно легко написать свой собственный.

Вот основа, которую я придумал за несколько минут и которая устанавливает двустороннюю привязку данных между двумя простыми свойствами:

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);

АвтоМаппер может копировать значения между двумя экземплярами, но вам придется написать собственный код, чтобы это происходило автоматически.

Может быть Привязываемый LINQ или непрерывный linq может помочь здесь.Если вы пытаетесь добавить свойства модели, которые на самом деле являются «производными свойствами» ваших фактических обновляемых данных, чтобы упростить привязку пользовательского интерфейса, эти две платформы должны помочь.

я написал небольшой Связывать проект с полной поддержкой привязки между вложенными свойствами, асинхронными действиями привязки.Синтаксис не может быть проще:

//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);

Если вы определили свои свойства как Свойство зависимостиТы мог бы это сделать.И WF, и WPF имеют его реализацию (первая ссылка предназначена для WPF.Для ВФ это этот one), поэтому вам нужно решить, какой из них использовать, но обоих должно быть достаточно для ваших нужд.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top