2015-01-03 4 views
1

Получите хорошую помощь здесь ранее относительно получения собственности из другого класса с помощью обработчика событий. Update property from interfaceСвойство не привязывается к виду

Результат - свойство, которое выглядит так на моем ViewModel, и оно не ведет себя знакомым способом.

public string Test 
    { 
     get { return _myInterface.Test; } 
     set {_myInterface.Test = value } 
    } 

Это свойство, которое я хотел бы привязать к моему представлению. Обычно я делал бы это так:

<TextBlock Text="{Binding Test}"/> 

Это свойство не работает. При зависании значения я вижу, что есть value. Но когда я нахожусь над именем свойства, ничего не происходит.

Edit:

public double Test 
    { 
     get { return _myInterface.Test; } 
     set 
     { 
      _myInterface.Test = value; 
      OnPropertyChanged("Test"); 
     } 

    } 

общественности новое событие PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propName) 
{ 
    if (this.PropertyChanged != null) 
    { 
     this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
    } 
} 

Полный код:

Интерфейс:

public interface IMyInterFace: INotifyPropertyChanged 
    { 

     string Test { get; set; } 
    } 

Класс, который реализует это:

public class MyClass : MyInterface 
    { 

     private string _test; 
     public string Test 
     { 
      get { return _test; } 
      set 
      { 
       _test = value; 
       OnPropertyChanged("Test"); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      var handler = this.PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 


     public void MyMetod() 
     { 
      //logic that updates Test 
     } 

ViewModel: (. Принимает IInterface в конструкторе)

public string Test 
     { 
      get 
      { 
       return _myInterface.Test; 
      } 
      set 
      { 
       _myInterface.Test = value; 
       OnPropertyChanged(); 
      } 
     } 


     public new event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      var handler = this.PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

OnPropertyChanged в VM не делает никогда попасть ..

UPDATE:

Это теперь мой взгляд, модель:

Я избавилась от MVVM-света, и теперь сделать это следующим образом:

public class ViewModel : INotifyPropertyChanged 
{ 
    public string Test 
      { 
       get { return _myInterface.Test; } 
       set 
       { 
        _myInterface.Test = value; 
        OnPropertyChanged("Test"); 
       } 

      } 

      public event PropertyChangedEventHandler PropertyChanged; 
      protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
      { 
       PropertyChangedEventHandler handler = PropertyChanged; 
       if (handler != null) 
       { 
        handler(this, new PropertyChangedEventArgs(propertyName)); 
       } 
      } 

} 

Но обработчик событий никогда не попадает. Value в Test-property никогда не присваивается должным образом. Даже при том, что я могу «видеть» значение при наведении курсора на value. Большое вам спасибо за помощь.

+1

Выглядит нормально. Он не будет обновляться, поскольку вы не реализовали 'INotifyPropertyChanged', но, кроме этого, он выглядит отлично. Вам нужно будет отправить больше кода. – nvoigt

+0

Спасибо, я сделал редактирование, где я (надеюсь, правильно) реализовал INotifyPropertyChanged. Тем не менее, обновление не видно. – Wranglerino

+0

Проверьте «DataContext» вашего объекта «Window» (или любого другого контейнера, который вы используете). [Snoop] (http://snoopwpf.codeplex.com/) может быть хорошим способом отладки вашей привязки. – dotNET

ответ

0

Вы должны реализовать INotifyPropertyChanged и поднять его при установке вашей Test как

public class YourClass : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     [NotifyPropertyChangedInvocator] 
     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      var handler = this.PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     public string Test 
     { 
      get 
      { 
       return _myInterface.Test; 
      } 
      set 
      { 
       _myInterface.Test = value; 
       OnPropertyChanged(); 
      } 
     } 
    } 
+0

По-прежнему не обновляется. Повесьте на 1 минуту и ​​больно опубликуйте полный код. – Wranglerino

0

вы пытались установить «UpdateSourceTrigger» в «PropertyChanged»?

Я также проверил бы DataContext. просто чтобы быть уверенным, попытайтесь оговаривая в DataSource

, например, если у вас есть ресурс с ключом под названием: «MainViewModel» тогда:

<TextBlock Text="{Binding Test,Source={StaticResource MainViewModel},UpdateSourceTrigger=PropertyChanged}"/> 

* Edit: пожалуйста, вы можете попробовать это реализация INotifyPropertyChanged вместо того, что у вас есть:

public event PropertyChangedEventHandler PropertyChanged = delegate { }; 

    protected void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

* Редактировать # 2: на свой последний кусок кода (ViewModel) выглядит, как вы забыли передать имя р для метода OnPropertyChanged().

public string Test 
     { 
      get 
      { 
       return _myInterface.Test; 
      } 
      set 
      { 
       _myInterface.Test = value; 
       OnPropertyChanged(); 
      } 
     } 
+0

Спасибо за советы, попробовал добавить: UpdateSourceTrigger = PropertyChanged. Тот же результат ... – Wranglerino

+0

см. Правки выше –

+0

По-прежнему не получает удар. В myClass, если я установил точку останова в настройке Test. Он останавливается, я могу «сменить страницу» в Visual Studio и посмотреть на ViewModel.cs-файл.Если вы держите мышь над значением, я могу увидеть правильное значение. Но это свойство не получает должным образом свойство. – Wranglerino

1

Вы прячасьPropertyChangedEventHandler в базовом классе вашего ViewModel с new в ключевом слове.

public new event PropertyChangedEventHandler PropertyChanged; 

Предположительно, ваш ViewModel наследуется от другого класса, который также реализует INotifyPropertyChanged. Если это так, вам не нужно переопределять интерфейс.

Update:

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

Учитывая существующий Notifier базовый класс:

public class NotifierBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

и реализатор:

public class MainWindowViewModel : NotifierBase 
{ 
    private bool someProperty; 
    public bool SomeProperty 
    { 
     get 
     { 
      return this.someProperty; 
     } 
     set 
     { 
      if (this.someProperty != value) 
      { 
       this.someProperty = value; 
       this.OnPropertyChanged(); 
      } 
     } 
    } 
} 

Когда я изменил класс модели представления следующим образом:

public class MainWindowViewModel : NotifierBase 
{ 
    private bool someProperty; 
    public bool SomeProperty 
    { 
     get 
     { 
      return this.someProperty; 
     } 
     set 
     { 
      if (this.someProperty != value) 
      { 
       this.someProperty = value; 
       this.OnPropertyChanged(); 
      } 
     } 
    } 

    public new event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

Это сломалось точно так же, как вы описываете. Используйте только PropertyChangedEventHandlerодин раз.

+0

Вы правы. Я использую MVVM-light, который позволяет моей VM наследовать RaisePropertyChanged. Даже после удаления «нового» ключевого слова он не попадает. Но я думаю, что мы можем подключиться к этому ... – Wranglerino

+0

Не просто удалять ключевое слово 'new' - удалять событие и метод из класса. Если свет MVVM (который я не знаю) дает вам базовый класс, который реализует 'INotifyPropertyChanged', просто используйте реализацию в базовом классе ... или не используйте базовый класс MVVMLight. Либо/или. Просто не имеют двух реализаций события, потому что это то, что вызывает вашу проблему. –

+0

Спасибо! Если хотите, просмотрите обновление. – Wranglerino

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