Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > WPF и Silverlight > Привязка текста к свойству из класса


Автор: fromrus 16.10.2008, 20:10
Ссылка на оригинал

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/ce9a2d5e-82c4-4930-bc73-9022034c6722

Повторюсь:нужно всего лишь привязать свойство к элементу?На мсдн форуме посоветовали то,что вы видите выше...В книгах я такого не встречал,везде привязывалось "напрямую".Кому верить?Чтоб привязать нужно свойство регистрировать целое?

Автор: Partizan 16.10.2008, 21:15
fromrus, с DependencyProperty точно заработает...

но в конце топика там посоветовали присовить объект содержащий свойство Chairs в качестве DataContext текстблоку

Автор: fromrus 16.10.2008, 21:53
попробовал присвоить DataContеxt Textblock'a "this",а потом и "Window1" -не работает даж в случае Dep prop...

Автор: Partizan 16.10.2008, 22:30
fromrus, ElementName пробовали установить?

Автор: rooks 17.10.2008, 23:20
Цитата(fromrus @ 16.10.2008,  21:53)
попробовал присвоить DataContеxt Textblock'a "this",а потом и "Window1" -не работает даж в случае Dep prop...

если класс не статический, то Binding нужно писать в коде а не в xaml-е

Автор: Idsa 18.10.2008, 14:55
fromrus, правильно ли я понял, что Вам нужно привязать к элементу свойство из codebehind этого же класса? С такой задачей я как раз столкнулся вчера и, подумав, реализовал следующим образом:
Код

Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=StrokeThickness, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

Работает так: добираемся по дереву до окна и считываем/записываем его свойство FillBrush (которое должно быть public). Работает, но не так, как хотелось бы. Во-первых, весь этот огород с RelativeSource - не самое красивое и производительное решение. Во-вторых, без реализации интерфейса INotifyPropertyChanged в классе формы (а реализовывать этот интерфейс в классе формы, на мой взгляд, неправильно) как такового TwoWay режима не получится: Binding движок не узнает о том, что Вы в коде изменили значение переменной. Поэтому при каждом изменении переменной в коде необходимо ручками вызывать UpdateSource... так что баиндинг теряет смысл.
Взглянув на это безобразие, решил перенести свойства из формы в отдельный статический класс настроек (который к тому же реализовывал бы INotifyPropertyChanged). Однако, и с реализацией этой идеи меня ждал неприятный сюрприз (карма у меня такая smile ). Дело в том, что TwoWay binding со статическим свойством реализовать невозможно.
Код

Text="{Binding Source={x:Static Someclass.SomeProperty"}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

С модификатором TwoWay данный вариант не прокатит. Binding из Source в Target очевиден: свойству Text присваем ссылку, которую получаем из Source. Однако в обратном направлении баиндинг невозможен: какому свойству Source присвоить новое значение указывается через свойство Path, которое в этом случае не задается. Поэтому такой вариант возможен только для OneWay привязки.

На workaround меня натолкнул этот блогпост: http://pavanpodila.spaces.live.com/blog/cns!9C9E888164859398!301.entry (последний коммент must read).
Я реализовал singleton класс, реализующий интерфейс INotifyChanged. Singleton в этом случае нужен для эмуляции статического класса.
Код

 public class Settings : INotifyPropertyChanged
  {
    private static Settings _instance;

    private Settings()
    {

    }

    public static Settings Instance
    {
      get
      {
        if (_instance == null)
          _instance = new Settings();
        return _instance;
      }
    }

    private SolidColorBrush _strokeBrush;
    public SolidColorBrush StrokeBrush
    {
      get
      {
        return this._strokeBrush;
      }
      set
      {
        this._strokeBrush = value;
        this.NotifyPropertyChanged("StrokeBrush");
      }
    }

    private int _strokeThickness;
    public int StrokeThickness
    {
      get
      {
        return this._strokeThickness;
      }
      set
      {
        this._strokeThickness = value;
        this.NotifyPropertyChanged("StrokeThickness");
      }
    }

    private SolidColorBrush _fillBrush;
    public SolidColorBrush FillBrush
    {
      get
      {
        return this._fillBrush;
      }
      set
      {
        this._fillBrush = value;
        this.NotifyPropertyChanged("FillBrush");
      }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string info)
    {
      if (this.PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
  }

Теперь я могу баиндить настройки вот таким элегантным (и более производительным, чем через RelativeSource) способом:
Код

Text="{Binding Source={x:Static local:Settings.Instance}, Path=StrokeThickness, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"


Добавлено @ 14:57
Забыл добавить, что, действительно, можно реализовать данный функционал через DependencyProperties. Это, как минимум, избавит программиста от необходимости реализации интерфейса INotifyPropertyChanged.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)