Привязка WPF не работает с UserControl

В моем MainViewModel у меня есть свойство, которое устанавливается пользователем. Когда будет получено новое значение, я хотел бы обновить информацию на моем UserControl. Проблема в том, что привязка не работает. Я хотел бы, чтобы это работало следующим образом. После изменения SelectedDay свойство Day в коде пользовательского элемента управления также изменяется, вызывая, таким образом, метод CalculateDay. Однако этот метод никогда не вызывается!

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

Код у меня есть:

Модель главного представления

private Day _selectedDay;
public Day SelectedDay
{
    get { return _selectedDay; }
    set
    {
        _selectedDay = value;
        RaisePropertyChanged("SelectedDay");
    }
}

XAML для основного окна

<controls:DayControl Day="{Binding SelectedDay, Mode=TwoWay}"></controls:DayControl>

Код UserCotrol позади

public Day Day
{
    get { return (Day)GetValue(DayProperty); }
    set
    {
        SetValue(DayProperty, value);
        CalculateDay();
    }
}

public static readonly DependencyProperty DayProperty =
    DependencyProperty.Register("Day", typeof(Day), typeof(DayControl), new PropertyMetadata(new Day()));

person Dmitry Korolev    schedule 19.05.2013    source источник


Ответы (2)


Согласно этому msdn

Во всех случаях, кроме исключительных, реализации вашей оболочки должны выполнять только действия GetValue и SetValue соответственно. Причина этого обсуждается в разделе Загрузка XAML и свойства зависимостей.

Вместо этого следует использовать PropertyChangedCallBack в определении свойства зависимости. Ниже приведен код, взятый непосредственно из msdn.

public static readonly DependencyProperty AquariumGraphicProperty = DependencyProperty.Register(
  "AquariumGraphic",
  typeof(Uri),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(null,
      FrameworkPropertyMetadataOptions.AffectsRender, 
      new PropertyChangedCallback(OnUriChanged)
  )
);

Определите свой CalculateDay вместо OnUriChanged выше.

person Jatin    schedule 19.05.2013
comment
Спасибо за совет, он действительно хороший. Однако это не решает мою проблему. SetValue() также не вызывается и свойство Day не обновляется. - person Dmitry Korolev; 19.05.2013
comment
Поскольку WPF полностью обходит оболочки, вам не следует добавлять какую-либо дополнительную логику в определения набора оболочек для вашего пользовательского свойства зависимостей. Если вы поместите такую ​​логику в определение набора, то логика не будет выполняться, когда свойство установлено в XAML, а не в коде. Вы не можете гарантировать вызов Wrappers Get/Set. Так что отбросьте всю логику из ваших Wrappers и вставьте в PropertyChangedCallback. Оболочка свойства Day является частью определения свойства Dependency, а не вашей ViewModel. Get не может быть вызван, когда вы читаете свойство Day в своем коде. То же самое для набора - person Jatin; 20.05.2013

Я не вижу причин, по которым вы используете DependencyProperty в коде позади. У вас есть все, что вам нужно в MainViewModel.

В коде просто добавьте в конструктор:

this.DataContext = new MainViewModel(); 

Затем переместите метод CalculateDay в MainViewModel и вызовите его в методе set SelectedDay.

person Rafal    schedule 19.05.2013