【问题标题】:UWP: binding to view model propertyUWP:绑定到视图模型属性
【发布时间】:2017-12-21 13:01:40
【问题描述】:

在我的视图模型中:

public string MyProperty{ get; set; }

public MyViewModel()
{
     MyProperty = "hello";
}

我已经定义了一个字符串属性。

现在,我想从我的页面绑定到这个属性:

Text="{Binding MyProperty}"

但这不起作用 - 没有显示任何文字。我错过了什么?

编辑: 我的视图模型继承自:

public class Observable : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
        {
            if (Equals(storage, value))
            {
                return;
            }

            storage = value;
            OnPropertyChanged(propertyName);
        }

        protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

编辑 2:

我已经修改了我的视图模型:

private string _myProperty;

        public string MyProperty
        {
            get => _myProperty;
            set => Set(ref _myProperty, value);
        }

        public MyViewModel()
        {
            _myProperty = "hello";
        }

和 xaml:

Text="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

但它仍然无法正常工作。

编辑3:我认为问题在于Text属性是自定义控件的注册依赖属性:

public sealed partial class MyControl : UserControl
    {
        public MyControl()
        {
            InitializeComponent();
            DataContext = this;
        }

        public string Text
        {
            get => (string)GetValue(s_textProperty);
            set => SetValue(s_textProperty, value);
        }

        public static readonly DependencyProperty s_textProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(MyControl), new PropertyMetadata(null));
    }

在控件的 xaml 中我有:

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

这个:

<MyControl Text="{Binding MyProperty}"/>

在我使用自定义控件的页面中。

【问题讨论】:

  • 您是否在视图上设置了数据上下文? var view = new MyView(); var viewModel = new MyViewModel(); view.DataContext = viewModel;
  • @JanWidmer 我有。
  • 要绑定标签的文字吗?
  • 在属性的getter和setter中放一个调试点?
  • 您是否在输出窗口中遇到任何绑定错误?

标签: c# mvvm uwp


【解决方案1】:

您的类应该实现 INotifyPropertyChanged 并具有如下属性访问器:

public event PropertyChangedEventHandler PropertyChanged;

private string _myProperty;

public string MyProperty
{
    get { return _myProperty; }
    set
    {
        _myProperty = value;
        OnPropertyChanged();
    }
}

private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

在 XAML 中:

Text="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

备注:

Mode = TwoWay - 如果由其中任何一个更改,属性将在 UI 和代码中同时更改。 UpdateSourceTrigger - 对 PropertyChanged 事件作出反应。 另外,请阅读 DataContext :)

【讨论】:

  • 我推荐了一个带有 [AddINotifyPropertyChangedInterface] 的类 BaseViewModel 并且每个 ViewModel 都实现了这个
  • 我实际上继承自Observable。我已经编辑了我的问题。
  • @Eutherpy,您仍然缺少 getter 和 setter 方法。查看我的“MyProperty”的正文 :)
  • @JanWidmer,是的,我也会这样 :) 但这将是很多与原始问题关系不大的代码 :)
  • @Eutherpy,另外,我现在记得的一件事 - 如果您正确检测了 NotifyPropertyChanged(主要在 setter 中),在您更改值并命中 setter 之后,应该立即命中 getter以及(由于获得 UI 的实际价值)
【解决方案2】:

我建议添加 PropertyChanged.Fody Nuget (https://www.nuget.org/packages/PropertyChanged.Fody/)

实现起来很简单。

[AddINotifyPropertyChangedInterface]
public class MyViewModel
{
    public string MyProperty { get; set; }

    public MyViewModel()
    {
        MyProperty = "hello";
    }
}

正如@DavidHruška 所说,也可以在 XAML 中编辑绑定。

【讨论】:

    【解决方案3】:

    您的 setter 需要显式调用 Observable.Set() 方法:

    private string _myProperty;
    public string MyProperty
    { 
       get {  return _myProperty; }
       set { this.Set<string>(ref _myProperty, value); }
    }
    

    不幸的是,汽车并没有为你实现 INPC,所以你不能使用它们。微软将此作为feature request,但似乎被拒绝了。

    【讨论】:

      猜你喜欢
      • 2018-05-25
      • 1970-01-01
      • 2010-12-02
      • 2011-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      • 2013-03-22
      相关资源
      最近更新 更多