【问题标题】:Trying to get pass property updates from objects to gui via data binding试图通过数据绑定将属性更新从对象传递到 gui
【发布时间】:2020-01-10 16:27:33
【问题描述】:

所以我有一个简单的 wpf 应用程序,我将其用作练习。 它基于动物园的想法,我有 3 种动物类型(大象、长颈鹿、猴子)。

每个都有一个健康属性和一个 IsDead 属性。

这两个属性都是 Animal 类的一部分,我的 Elephant 类、Giraffe 类和 Monkey 类都继承自该类。

我希望能够以更改健康字段为例,并使用这些值更新列表视图。

到目前为止,所创建的项目都没有在屏幕上更新。我知道这会很简单,但任何帮助都会很棒。提前致谢。

查看:

<ListView Margin="5"
          Name="lstMonkey"
          Width="150"
          ItemsSource="{Binding MonkeyList}">
  <ListView.View>
    <GridView>
      <GridView.Columns>
        <GridViewColumn Header="Index" />
        <!-- DisplayMemberBinding="{Binding Path=}" /-->
        <GridViewColumn Header="Health"
                        DisplayMemberBinding="{Binding Path=Monkey.Health}" />
        <GridViewColumn Header="Is Dead"
                        DisplayMemberBinding="{Binding Path=Monkey.IsDead}" />
      </GridView.Columns>
    </GridView>
  </ListView.View>
</ListView>

型号:

public class Monkey : Animal
{
  const int m_MinimumHealth = 30;

  public void CheckIsDead()
  {
    if (Health < m_MinimumHealth)
    {
      IsDead = true;
    }
    else IsDead = false;
  }
}

public class Animal
{
  public event PropertyChangedEventHandler PropertyChanged;

  private void OnPropertyChanged(string propertyname)
  {
    if (PropertyChanged != null)
    {
      PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
    }
  }

  public float Health
  {
    get { return m_Health; }
    set
    {
      m_Health = value;
      OnPropertyChanged("Health");
    }
  }

  public bool IsDead
  {
    get { return m_IsDead; }
    set
    {
      m_IsDead = value;
      OnPropertyChanged("IsDead");
    }
  }

  public int Index
  {
    get { return m_Index; }
    set
    {
      m_Index = value;
      OnPropertyChanged("Index");
    }
  }
}

public class MainWindowViewModel
{
  public MainWindowViewModel()
  {
    MonkeyList = new ObservableCollection<Monkey>();
    for (int i = 0; i < 5; i++)
    {
      MonkeyList.Add(new Monkey {Index = i, Health = 100, IsDead = false});
    }

    OnPropertyChanged("MonkeyList");
  }

  public event PropertyChangedEventHandler PropertyChanged;

  private void OnPropertyChanged(string propertyname)
  {
    if (PropertyChanged != null)
    {
      PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
    }
  }
}

【问题讨论】:

  • 请删除您的代码 cmets。我已将它们添加到您的问题中。
  • 确保有一个 MainWindowViewModel 实例分配给 MainWindow 的 DataContext。除此之外,Path=Monkey.HealthPath=Monkey.IsDead 应该是 Path=HealthPath=IsDead
  • 感谢您组织得更好。 BionicCode,以供将来参考,这样做的最佳方法是什么,以便在将其放入问题时可读?

标签: c# wpf listview mvvm binding


【解决方案1】:

问题是您的 ObservableCollection 不是属性。常见错误...我昨天只花了一个小时处理同样的问题。 XAML 将忽略 ViewModel 中的字段,因此所有绑定都必须是属性。如此定义:

public ObservableCollection<Monkey> MonkeyList { get; } = new ObservableCollection<Monkey>();

【讨论】:

  • 你怎么知道的?问题中的代码没有显示 MonkeyList 的声明。除此之外,如果你在视图模型中声明一个属性,要么将其设为只读(如public ObservableCollection&lt;Monkey&gt; MonkeyList { get; } = new ObservableCollection&lt;Monkey&gt;();),要么从其设置器中触发 PropertyChanged 事件。 ObservableCollection 类不能神奇地做到这一点。
  • @Clemens,它在代码中...向下滚动到 MainWindowViewModel。这是第5行。 ObseervibaleCollection 是专门为在集合更改时引发属性更改通知事件而创建的。这不是魔术,它是专门为此设计的。如果您不相信我,请自行阅读规范:docs.microsoft.com/en-us/dotnet/api/…
  • @Clemens,不过你把它设为只读是对的;这是一个很好的做法,因为 PropertyChanged 事件不会在您将新对象分配给 OC 属性时触发,它仅在集合更改时触发。
  • 这不是您可能假设的局部变量。它是对在别处声明的 MonkeyList 成员的赋值。
  • 啊,我明白你在说什么。那么视图的 DataContext 到底是什么?通过命名约定,只能假设它的 MainWindowViewModel。无论上下文如何,都需要有一个公共属性“MonkeyList”,否则没有什么可以绑定的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多