2013-04-05 2 views
2

В ViewModels существует, как правило, много этихBindable поля в ViewModel

private string someField; 
public string SomeField 
{ 
    get 
    { 
     return someField; 
    } 
    set 
    { 
     someField = value; 
     NotifyOfPropertyChanged(() => SomeField); 
    } 
} 

Есть ли способ, чтобы получить короткий вариант такой конструкции, что даже Bindable?

Так что у вас есть только написать что-то вроде:

public Bindable<string> SomeField; 

возможно с действием, которое должно быть уволено за NotifyPropertyChanged ...

+0

Нет дубликата, так как на вопрос не ответили в пределах возможного дубликата. –

+0

привязка работает только с публичными объектами. Вот как работает привязка wpf. так короткий ответ: НЕТ. вы должны привязываться к свойствам – blindmeis

ответ

3

Я полагаю, вы можете создать свой собственный класс, который сохраняет значение и поднимает INotifyPropertyChanged против вмещающего класса, который вы могли бы создать как:

public Bindable<string> SomeField = new Bindable<string>("test", this); 

а потом Binding против SomeField доступ будет содержащейсом значения и установить его может привести к INotifyPropertyChanged воспитывается против this

Вы должны были бы использовать некоторые неявные оператор приведения для того, чтобы получить обязательную систему, чтобы видеть ваш Bindable<T> как источник T и место поставить T

См: http://msdn.microsoft.com/en-us/library/85w54y0a.aspx

Что-то вдоль линий следующих может хватить:

public class Bindable<T> 
{ 
    private T _value; 
    private PropertyChangedEventHandler _notifyHandler; 
    private INotifyPropertyChanged _notifyTarget; 
    private string _name; 

    public Bindable(PropertyChangedEventHandler notifyHandler, INotifyPropertyChanged notifyTarget, string name, T value = default(T), bool trigger = false) 
    { 
     _value = value; 
     _name = name; 
     _notifyHandler = notifyHandler; 
     _notifyTarget = notifyTarget; 

     if (trigger) 
     { 
      _notifyHandler(_notifyTarget, new PropertyChangedEventArgs(_name)); 
     } 
    } 

    public implicit operator T(Bindable<T> bindable) 
    { 
     return bindable._value; 
    } 

    public implicit operator Bindable<T>(T value) 
    { 
     return new Bindable<T>(_notifyHandler, _notifyTarget, _name, value, true); 
    } 
} 

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


При дальнейшем исследовании предложенным моем решения я обнаружил, что это было бы проблематично попасть на работу из-за неявные отлитый из T в Bindable<T>, чтобы вспомнить цели и другие детали, я уверен, такое решение содержит достаточно идей, чтобы привести к рабочему.

+0

Я думаю, что система привязки должна даже видеть только 'T' ... или возникнут некоторые проблемы при связывании, например. строки в TextBox.Text или что нравится –

+0

Клинт, это классная идея, но вы проверили, что она действительно работает с привязкой данных? У меня есть сомнения. Но есть простой способ обхода: добавьте свойство 'Value', которое инкапсулирует' _value' и представляет собой просто свойство уведомления о реализации. Затем привязка должна была бы использовать это свойство. Однако это может быть проблематично в сочетании с Caliburn.Micro. –

+0

@ DanielHilgarth Я не тестировал этот код прямо нет, я сделал что-то подобное раньше, хотя, потому что я ленив, и 'INotifyPropertyChanged' может стать настоящей болью для повторного использования снова и снова, принцип звучит, даже если код не совсем: P Но согласились, некоторые рамки, которые сами причудливо отражают вещи, могут иметь проблемы. – Clint

0

Существуют свойства auto, которые могут использоваться как ярлык для свойств без логики.

Две следующие свойства эквивалентны:

private string someField; 
public string SomeField 
{ 
    get { return someField; } 
    set { someField = value; } 
} 

public string SomeField { get; set; } 

Однако, нет никакого встроенного способа представить уведомление об изменении в этом.

Но если вы хотите инвестировать время и/или деньги, есть способы сделать авто свойства уведомлять об изменениях:

  1. Использование АОП как PostSharp. Он будет вводить эту функциональность на этапе после компиляции: http://www.postsharp.net/model/inotifypropertychanged. Недостатком такого подхода является то, что PostSharp не является бесплатным.
  2. Используйте динамически созданные классы прокси. Во время выполнения вы можете создать класс, который происходит из вашего фактического ViewModel и переопределяет каждое свойство с уведомлением об изменении. Недостатком такого подхода является то, что вам нужно будет использовать этот прокси вместо вашего класса и что все ваши свойства должны быть виртуальными.
+0

Autoproperty не отвечает на мой вопрос ... –

+0

@MareInfinitus: Почему вы так говорите? Авто недвижимость сама по себе действительно не является решением, но это не ядро ​​моего ответа. –

+0

, потому что, по сути, автопроблемы не имеют ничего общего с моим вопросом. –

Смежные вопросы