Reputation: 517
I have a nice little Data Grid and I am trying to implement a system of "Dirty Flags". The flags update properly whenever i change a value manually, but when I save my changes to a database, the flags remain triggered.
Here is the relevant XAML for my DataGrid:
<DataGrid Margin="20" AutoGenerateColumns="False" Name="MasterDataGrid" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="MasterDataGrid_SelectionChanged" AlternationCount="2" DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" >
<DataGrid.Columns>
<DataGridTextColumn x:Name="NameColumn" IsReadOnly="True" Header="Name" Binding="{Binding Name}" />
<!--<DataGridTextColumn Header="Value" Binding="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=Explicit}">
<DataGridTextColumn.Foreground>
<MultiBinding Converter="{StaticResource MvcForeground}">
<Binding Path="Value" />
<Binding Path="DefaultValue"/>
</MultiBinding>
</DataGridTextColumn.Foreground>
</DataGridTextColumn>-->
<DataGridTemplateColumn Header="Value">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<Grid FocusManager.FocusedElement="{Binding ElementName=textBox1}">
<TextBox Name="textBox1" GotFocus="TextBox1_OnGotFocus" Margin="0" Padding="-2" MaxHeight="29" Text="{Binding Path=TemporaryValueFromUser, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<TextBlock Name="ValueTextBlock" Text="{Binding Path=TemporaryValueFromUser, Mode=TwoWay,UpdateSourceTrigger=Explicit}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground">
<Setter.Value>
<MultiBinding Converter="{StaticResource MvcForeground}">
<Binding Path="TemporaryValueFromUser" />
<Binding Path="StoredValue"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn IsReadOnly="True" Header="Stored Value" Binding="{Binding StoredValue, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn IsReadOnly="True" Header="Default Value" Binding="{Binding DefaultValue}"/>
</DataGrid.Columns>
</DataGrid>
The primary focus here is the "Value" column, as well as the "StoredValue" column to an extent.
My C# is in the code-behind, so no extra Data Context should be needed.
Here is the Multi Value Converter used in the XAML:
public class MvcForeground : IMultiValueConverter
{
public object Convert(object[] values, System.Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
//var changed = Brushes.Red;
var changed = Brushes.Red;
var unchanged = Brushes.Black;
if (values[0] == null || values[1] == null)
{
return unchanged;
}
if (values.Count() == 2)
{
if (values[0].Equals(values[1]))
return unchanged;
else
return changed;
}
else
return unchanged;
}
public object Reset()
{
return Brushes.Black;
}
public object[] ConvertBack(object value, System.Type[] targetTypes, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Here is my method for saving changes:
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
foreach (CmcdConfigurationParameter cp in MasterDataGrid.ItemsSource)
{
cp.StoredValue = cp.TemporaryValueFromUser;
}
_objDbContext.SaveChanges();
RaiseEvent(new RoutedEventArgs(SaveConfigChangesEvent));
MessageBox.Show("Changes have been saved to database");
}
The value converter works properly, and the save method does indeed write to the database, the only problem is that the UI does not update after the fact, probably because the Convert()
method is not called then.
How, then, can I force the UI to reflect the saved changes after I press the save button?
Upvotes: 0
Views: 284
Reputation: 20451
As you are not using the MVVM pattern with PropertyChanged notifications, the grid needs to be re-bound to the ItemsSource data.
At the end of your SaveButton_Click method, you need something like the following:
MasterDataGrid.ItemsSource = MasterDataGrid.ItemsSource.Cast<object>.ToList();
Upvotes: 1