开发者

Silverlight 4 Datagrid not updating when new entity added to DomainContext's entity set. (Binding problem?)

I have a DataGrid bound to a DomainDataSource:

<sdk:DataGrid AutoGenerateColumns="False" Height="Auto"
     ItemsSource="{Binding ElementName=mailboxDomainDataSource, Path=Data,Mode=TwoWay}"   
     Name="mailboxHeaderDataGrid"....>...</sdk>

I also have an add button to add a new row:

    private void addMailboxButton_Click(object sender, RoutedEventArgs e)
    {
        Mailbox m = new Mailbox();

        InboxNotifierDomainContext context = (InboxNotifierDomainContext)mailboxDomainDataSource.DomainContext;
        ((InboxNotifierDomainContext)mailboxDomainDataSource.DomainContext).Mailboxes.Add(m);
        if (!mailboxDomainDataSource.DomainContext.IsSubmitting) if (mailboxDomainDataSource.HasChanges) mailboxDomainDataSource.SubmitChanges();
        mailboxHeaderDataGrid.ItemsSource = ((InboxNotifierDomainContext)mailboxDomainDataSource.DomainContext).Mai开发者_Go百科lboxes;

        foreach (Mailbox m1 in ((InboxNotifierDomainContext)mailboxDomainDataSource.DomainContext).Mailboxes)
        {
            MessageBox.Show(m1.MailboxID + '-' + m1.MailBox1);
        }
    }

Now, when I iterate through DomainContext.Mailboxes, as at the end of the function, the new mailbox exists.

When I look in my database, the new mailbox exists.

If I refresh the page, the new mailbox appears in the DataGrid.

However, when I iterate through the ItemsSource, the new mailbox doesn't appear (shouldn't it be the same as DomainContext.Mailboxes, since I set them equal?). And the new mailbox doesn't appear in the grid.

Any help would be wonderful.

Thanks in advance!


You could try adding the following line in your code, setting the ItemsSource = null before assigning a new one:

// Set ItemsSource to null
mailboxHeaderDataGrid.ItemsSource = null;
// Assign new ItemsSource
mailboxHeaderDataGrid.ItemsSource = ((InboxNotifierDomainContext)mailboxDomainDataSource.DomainContext).Mailboxes;

However, looking at the xaml and the code I think you have some inconsistency there. In your xaml you use Binding ElementName=mailboxDomainDataSource, Path=Data and in your code you assign a new ItemsSource.

I believe a cleaner way would be to use an ObservableCollection<Mailbox> (namespace System.Collections.ObjectModel) as the ItemsSource and fill that with the results of the DomainDataSource. Use the DomainDataSource.LoadedData-Event and copy the results. (Something like this, not tested:)

private ObservableCollection<Mailbox> _mailboxCollection = new ObservableCollection<Mailbox>();
public ObservableCollection<Mailbox> MailboxCollection { ... }

private void DomainDataSource_LoadedData(object sender, LoadedDataEventArgs e)
{
  if (e.HasError)
  {
    // Error handling
  }
  else
  {
    if (e.Entities.Count > 0)
    {
      this.MailboxCollection = new ObservableCollection(e.Entities);
    }
  }
}

Then, when you add a new Mailbox, you can do this:

((InboxNotifierDomainContext)mailboxDomainDataSource.DomainContext).Mailboxes.Add(m);
this.MailboxObservableCollection.Add(m);


This is better way to do it,

private void addMailboxButton_Click(object sender, RoutedEventArgs e)
{
     Mailbox m = new Mailbox();
     mailboxDomainDataSource.DataView.Add(m);
     // it takes a little while for Datagrid to update so 
     // we will queue our selection logic
     Dispatcher.BeginInvoke( ()=>{
         mailBoxGrid.SelectedItem = m;
     } );
}


My favourite way to do this is as follows:

InboxNotifierDomainContext _context = mailboxDomainDataSource.DomainContext as InboxNotifierDomainContext;

_context.EntityContainer.GetEntitySet<Mailbox>().EntityAdded += (s,e) => {mailBoxGrid.ItemsSource = mailboxDomainDataSource.DomainContext.EntityContainer.GetEntitySet<Mailbox>();};

Alternatively, you can use the event args to get the added entity, cast it as a mailbox and and it to the ItemsSource--this was just the lazy way.

Might as well take advantage of C# being event-driven!

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜