I am trying to implement a "dirty flag" of sorts in my WPF Application, and I am running into some problems. I have a data grid, and one of the columns allows users to edit the Value
property of an item of a custom Device
class. In the future, the application will be linked to a database, so I want the user to be able to save changes to the database with a save button, which I have implemented. While the user has unsaved changes, I want the foreground of the value to be in red.
I tried solving this with a MultiValueConverter
, as seen in this SO question, but it is not working as expected. Here is the class containing my converter:
public class MvcForeground : IMultiValueConverter
{
public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var changed = Brushes.Red;
var unchanged = Brushes.Black;
if (values.Count() == 2)
{
if (values[0].Equals(values[1]))
return unchanged;
else
return changed;
}
else
return unchanged;
}
public object[] ConvertBack(object value, System.Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
And here is the entire XAML for my DataGrid. I don't think all of it is relevant to this issue, but I don't know for sure, so better to include it:
<DataGrid Margin="20" AutoGenerateColumns="False" Name="MasterDataGrid" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="MasterDataGrid_SelectionChanged" AlternationCount="2" DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<DataGrid.Columns>
<DataGridTextColumn IsReadOnly="True" Header="Name" Binding="{Binding Name}"/>
<DataGridTemplateColumn Header="Value">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<Grid FocusManager.FocusedElement="{Binding ElementName=textBox1}">
<TextBox Name="textBox1" GotFocus="TextBox_GotFocus" Margin="0" Padding="-2" MaxHeight="29" Text="{Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<!-- This is probably the relevant bit -->
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Value, Mode=TwoWay,UpdateSourceTrigger=Explicit}">
<TextBlock.Background>
<MultiBinding Converter="{StaticResource MvcForeground}">
<Binding Path="Value"/>
<Binding Path="Value" Mode="OneTime"/>
</MultiBinding>
</TextBlock.Background>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!-- End Probably Relevant Bit -->
<DataGridTextColumn IsReadOnly="True" Header="Default Value" Binding="{Binding DefaultValue}"/>
<DataGridTextColumn IsReadOnly="True" Header="Minimum" Binding="{Binding Minimum}"/>
<DataGridTextColumn IsReadOnly="True" Header="Maximum" Binding="{Binding Maximum}"/>
</DataGrid.Columns>
<DataGrid.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
According to the question I linked, that solution should work fine, but for some reason only the unchanged
state ever registers(The foreground, and background when I experimented with that instead, is only black, never red).
Now, the answer I linked is almost 9 years old, and I expect much has changed in WPF and C# since then. I have no idea how these MultiValueConverters
work, so My first instinct is to say that the problem lies in the values
array passed into the Convert()
method, as I have no idea where that is called.
That, however, is just a beginner's guess. Any help is greatly appreciated.
P.S. Yes, I do have the converter referenced in <Window.Resources>