【问题标题】:Accessing Properties of Properties in DataBinding在 DataBinding 中访问属性的属性
【发布时间】:2017-02-12 13:10:28
【问题描述】:

我的 ViewModel 中有两个公共属性 Foo 和 Bar。 Foo 只是一个字符串,Bar 是一个具有公共属性 Name 的类,它是一个字符串。

我想将Bar.Name 绑定到某个GUI 元素。 我该怎么做?

<Label Content="{Binding Foo}"> 按预期将字符串Foo 写入标签。

但是<Label Content="{Binding Bar.Name}"> 并没有将Bar 的名称写入Label。相反,标签保持为空。

编辑: 我的 XAML(以及标签)的 DataContext 设置为 ViewModel。

EDIT2:当然,真正的代码并不像上面描述的那么简单。我构建了一个仅代表上述描述的最小工作示例:

XAML:

<Window x:Class="MyTestNamespace.MyXAML"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
    <StackPanel>
        <Label Content="{Binding Foo}"></Label>
        <Label Content="{Binding Bar.Name}"></Label> <!-- Works fine! -->
    </StackPanel>
</Window>

视图模型:

namespace MyTestNamespace
{
    class MyVM
    {
        public string Foo { get; set; }
        public MyBar Bar { get; set; }

        public MyVM()
        {
            Foo = "I am Foo.";
            Bar = new MyBar("I am Bar's name.");
        }
    }

    class MyBar
    {
        public string Name { get; set; }

        public MyBar(string text)
        {
            Name = text;
        }
    }
}

事实上,这确实按预期工作。由于我无法与您共享实际代码(太多且归公司所有),因此我需要自己寻找原因。欢迎任何关于可能原因的提示!

【问题讨论】:

  • 您确定视图模型中 Bar 类实例的 Name 属性已填充(并且 Bar 属性已正确实例化)?您的标签(或父母之一或 DataTemplate)上的 DataContext 是如何设置的?
  • 是的,一切都设置正确。我可以在代码中使用Bar.Name 正常工作。 Bar 和 Bar.Name 都不是 null,永远。
  • 请分享代码以获得更多见解
  • 是Name 的构造函数中设置的Bar 或之后的值,如果是这样,您是否在设置值后引发属性更改事件?

标签: c# wpf data-binding properties


【解决方案1】:

感谢 Vignesh N. 的评论,我能够解决问题。

在实际代码中Bar可以改变,但一开始它的名字是一个空字符串。这是打开窗口时标签显示的内容。因为Label 不会在Bar 属性更改时收到通知,所以它不会更新。

解决方案:让 ViewModel 实现INotifyPropertyChanged 接口,并像这样定义Bar:

private MyBar _bar;
public MyBar Bar
{
    get
    {
        return _bar;
    }

    set
    {
        if (_bar != value)
        {
            _bar = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Bar)));
        }
    }
}

【讨论】:

    【解决方案2】:

    1.你的 Model.cs:

    public class Model : INotifyPropertyChanged
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                 PropertyChanged(this, new PropertyChangedEventArgs("Name"));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
    }
    

    2.你的 ViewModel:

      public MainViewModel()
      {
         _model = new Model {Name = "Prop Name" };  
      }
    
    
    
      private Model _model;
      public Model Model
      {
          get
          {
              return _model;
          }
          set
          {
              _model = value;     
          }
      }
    

    3.您的视图,将 DataContext 设置为您的 ViewModel:

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" 
        DataContext="{StaticResource MainViewModel}">
    <Grid>
        <Label Content="{Binding Model.Name}"/>
    </Grid>
    

    【讨论】:

      猜你喜欢
      • 2019-07-05
      • 1970-01-01
      • 1970-01-01
      • 2019-07-15
      • 2010-12-11
      • 2016-02-13
      • 2012-12-07
      • 2015-11-03
      • 2011-10-15
      相关资源
      最近更新 更多