开发者

WPF Data Binding with multiple controls

In WPF, I'm trying to bind multiple controls, but the second control isn't changing when the first control is changed.

I have two classes: a Task class, and a Log开发者_运维知识库 class, which is stored as a collection in the Task class. The list boxes below are bound to the Tasks, and the inner Logs for the selected Task.

The problem is that the list boxes are populated fine at first load, but if I select a different task, I'd expect the Logs to be update to the collection for the new Task, but it doesn't change from those from the originally selected task on first load. What am I missing?

In the designer:

    <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>

In the code behind:

public MainWindow()
        {
            InitializeComponent();

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

            this.DataContext = tasks.AsQueryable();
        }

The Task class:

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


Your Task class need to implement INotifyPropertyChanged interface so that as soon as there is any change in the underlying data it can tell WPF UI that something has changed now update/refresh your controls agains


Your task class need to implement INotifyPropertyChanged

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


You have to bind your first ListBox SelectedItem to object of Task model and add event handler for SelectionChanged. inside the this event you have to populate your logs by selected Task model also you have to implement INotifyPropertyChanged in your class.


It looks to me like the second binding should not work at all, as the DataContext is an enumerable of Tasks and the enumerable itself has no property called Logs. You could try working with IsSynchronizedWithCurrentItem and a binding to the current item:

<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>

You could also bind to the SelectedItem of the other ListBox but this introduces a redundant dependency between the controls. Also note that if you change any property in your data-objects you need to implement the interface mentioned by the other answerers, INotifyPropertyChanged.


I have it all working now. I implemented INotifyPropertyChanged, although that didn't solve the problem.

I am now using the MVVM pattern. This helped...the NoRM library I was using didn't have a SelectionChanged event. I created a View Model and was able to convert those Models to ObservableCollections. Now I'm just setting the Logs control DataContext on selection changed for the Task class.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜