I am trying to change the 'Background' of a button based on the 'changed' condition of an ObservableCollection. I have an 'IsDirty' boolean property on my ViewModel and I am sure it is getting updated when the ObservableCollection is changed.
However, the background of the button is not being changed and it doesn't appear that the 'Convert' method is ever being called.
What am I missing with my converter? The button's background should change to red when the ObservableCollection is changed (IsDirty is true)
EDIT
I updated the converter to return a value of red or green (instead of red and transparent) and the button has no background color so that would tell me the converter is never getting called.
EDIT 2
Added the ViewModel code showing the IsDirty property.
Converter
public class IsDirtyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return System.Convert.ToBoolean(value) ?
new SolidColorBrush(Colors.Red)
: new SolidColorBrush(Colors.Green);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
View
<Window x:Class="SerializeObservableCollection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:conv="clr-namespace:SerializeObservableCollection.Converter"
xmlns:ignore="http://www.ignore.com"
mc:Ignorable="d ignore"
Height="300"
Width="491"
Title="MVVM Light Application"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
<conv:IsDirtyConverter x:Key="IsDirtyConverter" />
</ResourceDictionary>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<TextBlock FontSize="36"
FontWeight="Bold"
Foreground="Purple"
Text="{Binding WelcomeTitle}"
VerticalAlignment="Top"
TextWrapping="Wrap" Margin="10,10,10,0" Height="54" HorizontalAlignment="Center" />
<DataGrid Margin="10,69,10,38"
ItemsSource="{Binding CodeCollection, Mode=TwoWay}"/>
<Button Name="SaveButton" Content="Save"
Command="{Binding SaveButtonClickedCommand}"
Background="{Binding
RelativeSource={RelativeSource Self},
Path=IsDirty,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource IsDirtyConverter}}"
HorizontalAlignment="Right" Margin="0,0,90,10"
Width="75" Height="20"
VerticalAlignment="Bottom"/>
<Button Content="Refresh" HorizontalAlignment="Right" Margin="0,0,10,10" Width="75"
Command="{Binding RefreshButton_Click}" Height="20" VerticalAlignment="Bottom"/>
</Grid>
</Window>
View Model
public class MainViewModel : ViewModelBase
{
public bool IsDirty;
/// <summary>
/// ObservableCollection of Codes
/// </summary>
private const string CodeCollectionPropertyName = "CodeCollection";
private ObservableCollection<Code> _codeCollection;
public ObservableCollection<Code> CodeCollection
{
get
{
if (_codeCollection == null)
{
_codeCollection = new ObservableCollection<Code>();
}
return _codeCollection;
}
set
{
if (_codeCollection == value)
{
return;
}
_codeCollection = value;
RaisePropertyChanged(CodeCollectionPropertyName);
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel(IDataService dataService)
{
// Load XML file into ObservableCollection
LoadXML();
}
private void LoadXML()
{
try
{
XmlSerializer _serializer = new XmlSerializer(typeof(Codes));
// A file stream is used to read the XML file into the ObservableCollection
using (StreamReader _reader = new StreamReader(@"LocalCodes.xml"))
{
CodeCollection = (_serializer.Deserialize(_reader) as Codes).CodeCollection;
}
// Change notification setup
CodeCollection.CollectionChanged += OnCodeCollectionChanged;
}
catch (Exception ex)
{
// Catch exceptions here
}
}
private void SaveToXML()
{
try
{
XmlSerializer _serializer = new XmlSerializer(typeof(ObservableCollection<Code>));
using (StreamWriter _writer = new StreamWriter(@"LocalCodes.xml"))
{
_serializer.Serialize(_writer, CodeCollection);
}
}
catch (Exception ex)
{
}
}
private RelayCommand _saveButtonClickedCommand;
public RelayCommand SaveButtonClickedCommand
{
get
{
return _saveButtonClickedCommand ??
(_saveButtonClickedCommand = new RelayCommand(
() =>
{
SaveButtonClicked();
}));
}
}
private void SaveButtonClicked()
{
SaveToXML();
}
private void OnCodeCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
IsDirty = true;
}
}