Here is the long-winded explanation to what is essentially a simple problem. I am using a Telerilk RadDropDownButton, which displays a list Items with checkboxes.
<Controls:RadDropDownButton AutoOpenDelay="0:0:0.0" x:Name="Urgency" VerticalAlignment="Center" Width="150" Content="{Binding Path=ItemsSource, ElementName=UrgencyList, Mode=TwoWay, Converter={StaticResource ButtonTextConverter}}" HorizontalContentAlignment="Left">
<Controls:RadDropDownButton.DropDownContent>
<ListBox x:Name="UrgencyList">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Content="{Binding Name}" ClickMode="Press" IsChecked="{Binding IsChecked, Mode=TwoWay}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Controls:RadDropDownButton.DropDownContent>
</Controls:RadDropDownButton>
As you can see, I bound the Content property to a Converter. What I want is, if nothing is selected, for the content to read "All", and if something is checked, to show a list of the # of selected (Checked) items.
public class ButtonTextConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Debug.WriteLine("I'm Binding");
int numChecked = 0;
if (value != null)
numChecked = ((ObservableCollection<UrgencyItem>) value).Count(urgencyItem => urgencyItem.IsChecked);
return numChecked > 0 ? string.Format("{0} Items Selected", numChecked) : "All";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
The class I am binding to implements INotifyPropertyChanged, as required. Partial listing here:
public class UrgencyItem : INotifyPropertyChanged
{
private int _id;
private bool _isChecked;
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
NotifyPropertyChanged("Name");
}
}
And I bind the ListBox to the Data in the code-behind, like this:
private void SearchParamsVertical_Loaded(object sender, RoutedEventArgs e)
{
urgencyList = new ObservableCollection<UrgencyItem>
{
new UrgencyItem {ID = 1, IsChecked = false, Name = "Non Emergent"},
new UrgencyItem {ID = 2, IsChecked = false, Name = "Emergent"},
new UrgencyItem {ID = 3, IsChecked = false, Name = "Stat Emergent"},
new UrgencyItem {ID = 4, IsChecked = false, Name = "Stroke Protocol"}
};
urgencyList.CollectionChanged += urgencyList_CollectionChanged;
UrgencyList.ItemsSource = urgencyList;
}
SO HERE'S THE PROBLEM...
When a checkbox is checked, the value of Content should update. It is not.
The reason it's not is because, although the notification is firing that the IsChecked was changed, that notification is basically going nowhere. The UrgencyItem object has no idea that it is part of an ObservableCollection. And the thing about an ObservableCollection is that it only sends notifications to it's binding when items are ADDED/REMOVED to/from the collection. In other words, changing the property of an item in the collection does not fire the CollectionChanged event, because no objects were added/removed.
What I need to do is have the collectionChanged event fire when I modify a property of the collection. I used to know how to do this, but too much time away from Silverlight and I've forgotten how.
Anyone?