如何仅当WPF ComboBoxItem是所选项并且满足条件时才对其设置属性
本文关键字:条件 属性 设置 满足 ComboBoxItem WPF 何仅当 选项 | 更新日期: 2023-09-27 18:19:27
只有当组合框项目是所选项目并且其基础ID与ItemSource中的最后一个ID匹配时,我才难以使组合框项目显示为红色字体。到目前为止,我得到的是,只有当它是所选项目时,它才会变成红色,但我如何检查底层属性"ID"是否与包含它的ObservableCollection中的最后一个项目匹配,即只有当SelectedItem的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>
因此,如果SelectedBillingCycle.ID!=BillingCycles[BillingCycle.Length-1].ID,文本应该显示为红色。我不知道我该如何引用BillingCycles[BillingCycles.Length-1]将其与.进行比较
///编辑:
更改了XAML,这越来越近了,但更改了所有组合框项,而不仅仅是selectedItem。我想我需要使用某种模板选择器,或者完全重新思考XAML。
试试这个:假设我有一个UserType类
public class UserType
{
public string Name { get; set; }
public string Description { get; set; }
}
并且我已经将UserType的ObservableCollection绑定到项目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>
多值转换器
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();
}
}
在您的情况下,DisplayMember路径将为BillingCycleDescription。
我最终不得不使用DataTemplateSelector类来区分SelectedItem和其他comboxItems:
public class ComboBoxItemTemplateSelector : DataTemplateSelector
{
public DataTemplate SelectedTemplate { get; set; }
public DataTemplate DropDownTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
ComboBoxItem comboBoxItem = container.GetVisualParent<ComboBoxItem>();
if (comboBoxItem == null)
{
return SelectedTemplate;
}
return DropDownTemplate;
}
}
这个扩展类:
public static T GetVisualParent<T>(this DependencyObject child) where T : Visual
{
while ((child != null) && !(child is T))
{
child = VisualTreeHelper.GetParent(child);
}
return child as T;
}
这是XAML:
<ComboBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding BillingCycles}" SelectedItem="{Binding SelectedBillingCycle}">
<ComboBox.ItemTemplateSelector>
<b:ComboBoxItemTemplateSelector>
<b:ComboBoxItemTemplateSelector.SelectedTemplate>
<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}}"/>
</MultiBinding>
</TextBlock.Foreground>
</TextBlock>
</DataTemplate>
</b:ComboBoxItemTemplateSelector.SelectedTemplate>
<b:ComboBoxItemTemplateSelector.DropDownTemplate>
<DataTemplate>
<TextBlock Text="{Binding BillingCycleDescription}" />
</DataTemplate>
</b:ComboBoxItemTemplateSelector.DropDownTemplate>
</b:ComboBoxItemTemplateSelector>
</ComboBox.ItemTemplateSelector>
</ComboBox>
使用这个转换器,我在Ethicalologs:的帮助下找到了这个转换器
public class IsCurrentCycleColorConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
SolidColorBrush color = new SolidColorBrush(Colors.Black);
if (values != null && values.Count() == 2)
{
var itemsSource = values[0] as ObservableCollection<BillingCycle>;//This is the Type of you Collection binded to ItemsSource
if (!(itemsSource != null && itemsSource.Any() && itemsSource.First() == (BillingCycle)values[1]))
{
color = new SolidColorBrush(Colors.DarkRed);
}
}
return color;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}