Reputation: 197
Got good help here earlier regarding getting a property from another class using an eventhandler. Update property from interface
The result is a property that looks like this on my ViewModel and it does not behave in a familiar way.
public string Test
{
get { return _myInterface.Test; }
set {_myInterface.Test = value }
}
This is a property that I would like to bind to my view. Normally I would do it like this:
<TextBlock Text="{Binding Test}"/>
It does not work on this specifik property.
When hovering over value I can see that the value
is there. But when i hover over the propertyname, nothing happens.
Edit:
public double Test
{
get { return _myInterface.Test; }
set
{
_myInterface.Test = value;
OnPropertyChanged("Test");
}
}
public new event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
Complete code:
Interface:
public interface IMyInterFace: INotifyPropertyChanged
{
string Test { get; set; }
}
Class that implements it:
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: (takes the IInterface in constructor.)
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));
}
}
The OnPropertyChanged in the VM does never get hit..
UPDATE:
This is now my view-model:
I got rid of MVVM-light and now do it like this:
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));
}
}
}
But the event-handler never gets hit. The Value
in the Test-property never gest assigned properly. Even though I can "see" the value when hovering over value
. Thank you very much for helping.
Upvotes: 1
Views: 163
Reputation: 58981
You're hiding the PropertyChangedEventHandler
in your viewmodel's base class with the new
keyword.
public new event PropertyChangedEventHandler PropertyChanged;
Presumably, your viewmodel is inheriting from some other class that also implements INotifyPropertyChanged
. If that's the case, you don't need to reimplement the interface.
Update:
I took an existing project of mine and broke it in the same way as follows:
Given an existing Notifier base class:
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));
}
}
}
and an implementor:
public class MainWindowViewModel : NotifierBase
{
private bool someProperty;
public bool SomeProperty
{
get
{
return this.someProperty;
}
set
{
if (this.someProperty != value)
{
this.someProperty = value;
this.OnPropertyChanged();
}
}
}
}
When I changed the view model class as follows:
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));
}
}
}
This broke in exactly the same way you're describing. Only implement the PropertyChangedEventHandler
once.
Upvotes: 1
Reputation: 31014
have you tried to set the "UpdateSourceTrigger" to "PropertyChanged"?
<TextBlock Text="{Binding Test,UpdateSourceTrigger=PropertyChanged}"/>
I would also check the DataContext. just to be sure, try to explicit mention the DataSource
for example if you got a resource with a Key named: "MainViewModel" then:
<TextBlock Text="{Binding Test,Source={StaticResource MainViewModel},UpdateSourceTrigger=PropertyChanged}"/>
*Edit: can you please try this implementation of INotifyPropertyChanged instead of what you have:
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
*Edit#2: on your last piece of code (ViewModel) looks like you forgot to pass the name of the property to the OnPropertyChanged() method.
public string Test
{
get
{
return _myInterface.Test;
}
set
{
_myInterface.Test = value;
OnPropertyChanged();
}
}
Upvotes: 0
Reputation: 356
You need to implement the INotifyPropertyChanged
and raise it when setting your Test
like
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();
}
}
}
Upvotes: 0