I have a DataGrid that binds to an ObservableCollection named Programs. On the window there's 2 buttons, one for changing a bit field in the selected row to Activate, the other to change it to Deactivate. Since we're using .EDMX files, so don't have access to the generated C# code for each model class, changing a value of the bit field in one of the rows of Programs doesn't change the value in the DataGrid. I understand that. I looked up here on SO how I might be able to do this. I found a post from almost 8 years ago, titled ObservableCollection not updating View. This looked very promising so I implemented the solution given by aqwert. However, it still is not working. I know the value is getting modified and following aqwert's solution I'm replacing Programs. Doesn't matter, it doesn't update the view.
We're using .NET Framework 4.5.2. We're also using MVVM Light. And we're using FirstFloor Software's ModernUI for WPF.
Here's the XAML for the DataGrid:
<DataGrid
Grid.Row="3"
Grid.Column="2"
AutoGenerateColumns="False"
BorderThickness="1"
CanUserAddRows="False"
ItemsSource="{Binding Programs}"
SelectedItem="{Binding SelectedProgram, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTemplateColumn
Width="Auto"
Header="ID"
IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ID}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn
Width="Auto"
Header="Abbrev"
IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ProgramAbbrev}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn
Width="Auto"
Header="Program Name"
IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ProgramName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn
Width="Auto"
Header="Inactive"
IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Inactive, Converter={StaticResource BoolToYN}}" TextAlignment="Center" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
Here's the definition of Programs from the VM:
private ObservableCollection<Program> programs;
public ObservableCollection<Program> Programs
{
get { return programs; }
set
{
if (programs != value)
{
programs = value;
RaisePropertyChanged("Programs");
}
}
}
and lastly, here's the code that I've made, following aqwert's solution:
//make a copy of Programs
var programsCopy = new List<Program>();
foreach (var item in Programs)
{
if (item.ID == SelectedProgram.ID)
{
item.Inactive = inactiveFlag;
item.UpdatedBy = Environment.UserDomainName + "\\" + Environment.UserName;
item.UpdatedOn = rightNow;
}
programsCopy.Add(item);
}
//copy over the top of Programs
Programs = new ObservableCollection<Program>(programsCopy);