属性不会绑定到视图

时间:2015-01-03 17:33:13

标签: c# wpf

早些时候在使用eventhandler从另一个类获取属性方面得到了很好的帮助。 Update property from interface

结果是一个在我的ViewModel上看起来像这样的属性,它的行为并不熟悉。

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

这是我想要绑定到我的视图的属性。通常我会这样做:

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

它不适用于此特定属性。 当悬停在值上时,我可以看到value存在。但当我将鼠标悬停在属性名称上时,没有任何反应。

编辑:

 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));
            }
        }

VM中的OnPropertyChanged永远不会被击中..

更新:

这是我的观点模型:

我摆脱了MVVM-light,现在这样做:

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));
                }
            }

}

但事件处理程序永远不会被击中。 Test-property中的Value永远不会被正确分配。即使我可以“悬停”value时“看到”该值。非常感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

您使用PropertyChangedEventHandler关键字隐藏您的viewmodel基类中的new

public new event PropertyChangedEventHandler PropertyChanged;

据推测,您的viewmodel继承自同样实现INotifyPropertyChanged的其他类。如果是这种情况,则无需重新实现界面。

更新

我拿了一个我现有的项目并按照以下相同的方式打破了它:

给定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 一次

答案 1 :(得分: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();
            }
        }
    }

答案 2 :(得分:0)

您是否尝试将“UpdateSourceTrigger”设置为“PropertyChanged”?

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

我还会检查DataContext。 只是为了确定,尝试明确提到DataSource

例如,如果您有一个名为“MainViewModel”的Key的资源 然后:

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

*编辑: 你可以试试这个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();
            }
        }