【问题标题】:WPF Data Binding with multiple controls具有多个控件的 WPF 数据绑定
【发布时间】:2011-07-31 18:54:55
【问题描述】:

在 WPF 中,我试图绑定多个控件,但是当第一个控件发生更改时,第二个控件没有更改。

我有两个类:Task 类和 Log 类,后者作为集合存储在 Task 类中。下面的列表框绑定到任务,以及选定任务的内部日志。

问题是列表框在第一次加载时填充得很好,但是如果我选择不同的任务,我希望日志会更新到新任务的集合中,但它不会改变那些从首次加载时最初选择的任务。我错过了什么?

在设计器中:

    <ListBox x:Name="listBoxTasks" ItemsSource="{Binding}" DisplayMemberPath="Key"
             Grid.Row="0" Grid.Column="0" Grid.RowSpan="2">
    </ListBox>
    <ListBox x:Name="listBoxLogs" 
             ItemsSource="{Binding Logs}" DisplayMemberPath="EntryDate"
             Grid.Row="1" Grid.Column="1">
    </ListBox>

在后面的代码中:

public MainWindow()
        {
            InitializeComponent();

            IMongoCollection<Task> tasks = DataManager.GetData();

            this.DataContext = tasks.AsQueryable();
        }

任务类:

public class Task : BusinessBase<Task>
{
    public ObjectId _Id { get; set; }
    public string Key { get; set; }
    public string Description { get; set; }
    public string Summary { get; set; }
    public string Details { get; set; }

    public IEnumerable<Log> Logs { get; set; }
    public IEnumerable<Link> Links { get; set; }
    public IEnumerable<String> RelatedKeys { get; set; }
    public IEnumerable<TaskItem> Items { get; set; }
}

【问题讨论】:

    标签: c# .net wpf xaml data-binding


    【解决方案1】:

    您的Task 类需要实现INotifyPropertyChanged 接口,以便一旦基础数据发生任何变化,它就可以告诉 WPF UI 发生了变化,现在再次更新/刷新您的控件

    【讨论】:

      【解决方案2】:

      你的任务类需要实现INotifyPropertyChanged

      http://msdn.microsoft.com/en-us/library/ms743695.aspx

      【讨论】:

        【解决方案3】:

        您必须将您的第一个ListBox SelectedItem 绑定到Task 模型的对象并为SelectionChanged 添加事件处理程序。在此事件中,您必须通过选定的任务模型填充日志,还必须在课堂上实现 INotifyPropertyChanged

        【讨论】:

          【解决方案4】:

          在我看来,第二个绑定根本不应该工作,因为DataContextTasks 的可枚举项,而可枚举项本身没有名为Logs 的属性。您可以尝试使用 IsSynchronizedWithCurrentItem 并绑定到当前项目:

          <ListBox x:Name="listBoxTasks" ItemsSource="{Binding}" DisplayMemberPath="Key"
                   Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"
                   IsSynchronizedWithCurrentItem="True"> <!-- Set this -->
          </ListBox>
          <ListBox x:Name="listBoxLogs" DisplayMemberPath="EntryDate"
                   Grid.Row="1" Grid.Column="1"
                   ItemsSource="{Binding /Logs}"> <!-- Note the slash which indicates a binding to the current item -->
          </ListBox>
          

          您也可以绑定到另一个ListBoxSelectedItem,但这会在控件之间引入冗余依赖关系。另请注意,如果您更改数据对象中的任何属性,您需要实现其他回答者提到的接口INotifyPropertyChanged

          【讨论】:

            【解决方案5】:

            我现在一切正常。我实现了 INotifyPropertyChanged,尽管这并没有解决问题。

            我现在正在使用 MVVM 模式。这有助于...我使用的 NoRM 库没有 SelectionChanged 事件。我创建了一个视图模型,并且能够将这些模型转换为 ObservableCollections。现在我只是在为 Task 类更改选择时设置 Logs 控件 DataContext。

            【讨论】: