Привязка данных в C # - имена свойств в виде строк - PullRequest
3 голосов
/ 19 июня 2011

После прочтения this я совершенно уверен, как свойство класса может быть связано с TextBox в моем UserControl.Тем не менее мне довольно неудобно получать доступ к свойствам через строки.Любая связь с типом или даже наличием этого свойства (с обеих сторон) теряется.
Мои основные проблемы с этим отношением заключаются в том, что:

  • IntelliSense перестает работать -> легко ошибитьсяменее удобно;
  • все, что написано там, не будет проверено, пока оно не будет вызвано -> ошибки, скорее всего, останутся незамеченными до самого худшего момента ...

Есть ли какой-то другой способсоздать UserControl, представляющий один класс, который связан с экземпляром этого класса и остается синхронизированным с ним?(кроме того, чтобы делать это вручную с событиями)

Ответы [ 3 ]

0 голосов
/ 19 июня 2011

Нет причин, по которым вы вынуждены использовать строки, это просто базовый механизм событий NotifyPropertyChanged. Например, Prism Framework предоставляет простую оболочку, которая принимает в качестве аргумента Linq `Выражение> и использует отражение, чтобы получить имя свойства (но будьте осторожны; в одном случае я видел, что это вызывает проблему производительности при использовании свойства, которое много раз обновлялось за короткий промежуток времени).

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

class NotificationObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    protected virtual void OnPropertyChanged( ProeprtyChangedEventArgs e )
    {
        PropertyChanged( this, e );
    }

    protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression )
    {
        // you'll want to add some error checking here
        var name = ((MemberExpression)propertyExpression).Member.Name;
        OnPropertyChanged( new PropertyChangedEventArgs( name ) );
    }
}

Теперь вы можете использовать его, просто передав свойство:

class Whatever : NotificationObject
{
    private string _foo = String.Empty;
    public string Foo
    {
        get { return _foo ?? String.Empty; }
        set
        {
            if( !_foo.Equals( value ) )
            {
                _foo = value;
                RaisePropertyChanged( this.Foo );
            }
        }
    }
}

Теперь, если вы когда-нибудь проведете рефакторинг свойства Foo, вам не придется беспокоиться об обновлении строки. Это не решает проблему с другой стороны, хотя. DependencyProperty будет, но у вас есть внутренняя проблема с строкой, причем IMP предпочтительнее, потому что это только дублирование в одном месте (в классе), а не n количество дубликатов извне. Это не идеально, но это помогает.

0 голосов
/ 19 июня 2011

Вы также можете проверить этот проект notifypropertyweaver , который помогает вам избежать волшебной струны и предлагает еще несколько интересных вещей.

0 голосов
/ 19 июня 2011

(помимо ручного управления событиями)

Необходимо уточнить, что одностороннее и двухстороннее связывание данных зависит от событий. Пожалуйста, прочитайте о Как: реализовать уведомление об изменении свойства

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

Одним из способов сделать это является использование пользовательских атрибутов. Вы можете украсить определенные свойства в своей модели данных, к которым должен привязываться пользовательский элемент управления. Таким образом, когда DataSource установлен в вашем пользовательском элементе управления, с помощью отражения вы можете искать в объекте DataSource для пользовательских Attribute декорированных свойств и связывать их:

public class MyDataModelObject
{
    public int NotBindableProperty { get; }

    [MyBindableAttribute]
    public string BindableStringProperty
    {
        get {...}
        set {...}
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...