3
votes

I'm new in WPF. Now, I'm writing a project of WPF with Entity Framework. I can add and delete items correctly on my wpf; however, after I add or delete items, my datagrid still didn't refresh. Even I use the ssEntities.SaveChanges(); ssEntities.Refresh(RefreshMode.StoreWins, ssEntities.User);

How can I refresh my datagrid automatically with refresh function or another function ?

XAML

<Window.Resources>
    <CollectionViewSource x:Key="UserViewSource" 
                          d:DesignSource="{d:DesignInstance my:User, CreateList=True}" />
</Window.Resources>
<DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="537"  
          HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="12,12,0,0" 
          Name="UserDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" 
          VerticalAlignment="Top" Width="300" 
          SelectedCellsChanged="UserDataGrid_SelectedCellsChanged">
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="IDColumn" Binding="{Binding Path=ID}" Header="ID"
                            Width="80" IsReadOnly="True" />
        <DataGridTextColumn x:Name="NameColumn" Binding="{Binding Path=Name}" 
                            Header="Name" Width="80" IsReadOnly="True" />
    </DataGrid.Columns>
</DataGrid>

cs

 private void btnSave_Click(object sender, RoutedEventArgs e)
 {
     try
     {
         if (ActionHandler == "Add")
         {
             User user = new User();   
             user.ID = ID;
             user.Name = Name;

             ssEntities.User.AddObject(user);
         }

         ssEntities.SaveChanges();
         ssEntities.Refresh(RefreshMode.StoreWins, ssEntities.User);
     }
     catch (Exception ex)
     { MessageBox.Show(ex.Message); }
 }
2
Post your XAML and code. - Federico Berasategui
@HighCore Here is my datagrid XAML and my save button, thanks. - CYB
1 - I don't see where your DataContext is being set. 2 - I don't think it's a good idea to mash altogether UI and DB access like that, you'd better create an intermediate object layer to hold the data as intended to be shown in the UI. You will need ObservableCollections for that. Please, don't put DB access code in a Button click event handler. - Federico Berasategui
isnt there a way to update the DataGrid datasource or databinding? In winforms I use DataGridView.Datasource = null and then I assign the list as a DataSource again. When you refresh it does refresh, but its the visual that does not shows properly. - Andres
@andres mmm... that's not the way to do it in WPF, he should be using ObservableCollections instead. Also, I don't see where the DataContext is being set, therefore I couldn't tell What the DataContext actually is. - Federico Berasategui

2 Answers

0
votes

I would agree with the others who commented in the other answer, you really should adopt MVVM for something like this.

That said, you said above that your DataContext is StudyEntities ssEntities;. Is that your ObjectContext? It looks like it is being used as one. I typically don't use a CollectionViewSource unless I need to do some custom filtering and/or sorting on a large-ish set of data. Otherwise I just use an ObservableCollection.

Something like this should suffice:

private ObservableCollection<User> MyUsers { get; set; }
private StudyEntities ssEntities;

public MyMainWindow()
{
    ssEntities = new StudyEntities();
    MyUsers = new ObservableCollection<User>(ssEntities.Users.ToList());
}

private void btnSave_Click(object sender, RoutedEventArgs e)
{
    //Code for creating the User isntance MyUser
    MyUsers.Add(MyUser);
    ssEntities.Users.Add(MyUser);
    ssEntities.SaveChanges();
}

Your entities are placed in an ObservableCollection so that they can be manipulated for the UI. When you click the button, it creates a user, adds it to the ObservableCollection and the ObjectContext, then saves changes. The ID that is generated for the record will be populated on save changes.

-1
votes

Assuming you are using the generic List you need to change the UpdateSourceTrigger in the binding, and bind a specific element (example listUser)

In your DataGrid, change:

ItemsSource="{Binding}" 

To:

ItemsSource="{Binding listUser, UpdateSourceTrigger=PropertyChanged}" 

Then in your code behind, implement INotifyPropertyChanged, and execute

OnPropertyChanged("listUser");

Source for property changed: http://msdn.microsoft.com/en-us/library/ms743695.aspx