I am having trouble making a combo box item appear with the font color red only when it is the selected item AND its underlying ID matches the last ID in the ItemSource. Here's what i've got so far, this makes it red only when it is the selected item, but how do i also check to see if the underlying property "ID" matches the last entry in the ObservableCollection that contains it, ie only when SelectedItem's ID== Collection[Length-1].ID?
<ComboBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding BillingCycles}" SelectedItem="{Binding SelectedBillingCycle}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding BillingCycleDescription}" >
<TextBlock.Foreground>
<MultiBinding Converter="{StaticResource IsCurrentCycleColorConverter}">
<Binding Path="ItemsSource" RelativeSource="{RelativeSource AncestorType={x:Type ComboBox}}"/>
<Binding Path="SelectedItem" RelativeSource="{RelativeSource AncestorType={x:Type ComboBox}}"/>
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ComboBoxItem}}"/>
</MultiBinding>
</TextBlock.Foreground>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
So, if SelectedBillingCycle.ID != BillingCycles[BillingCycle.Length-1].ID, the text should appear red. I'm not sure how I'd refer to the BillingCycles[BillingCycles.Length-1] to compare it to.
///EDIT:
Changed the XAML, this is getting closer but changes ALL the comboBoxItems, not just the selectedItem. I'm thinking I need to use a template selector of some kind or rethink the XAML completely.
Try this : Suppose i have a UserType class
public class UserType
{
public string Name { get; set; }
public string Description { get; set; }
}
and I have ObservableCollection of UserType binded to itemsSource of ComboBox
public ObservableCollection<UserType> UserTypes { get; set; }
xaml
<Window.Resources>
<local:ComboBoxForegroundConverter x:Key="ComboConv"/>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Foreground">
<Setter.Value>
<MultiBinding Converter="{StaticResource ComboConv}">
<Binding Path="ItemsSource" RelativeSource="{RelativeSource AncestorType={x:Type ComboBox}}"/>
<Binding Path="SelectedItem" RelativeSource="{RelativeSource AncestorType={x:Type ComboBox}}"/>
<Binding/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<ComboBox ItemsSource="{Binding UserTypes}" DisplayMemberPath="Name"/>
</StackPanel>
MultiValueConverter
public class ComboBoxForegroundConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values != null && values.Count() == 3)
{
var itemsSource = values[0] as ObservableCollection<UserType>;//This is the Type of you Collection binded to ItemsSource
if (itemsSource != null && itemsSource.Any() && itemsSource.Last() == values[1] && values[2]==values[1])
return new SolidColorBrush(Colors.Red);
}
return new SolidColorBrush(Colors.Black);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
In your case DisplayMember path will be BillingCycleDescription.