C# 如何仅当WPF ComboBoxItem是选定项且满足条件时才设置其属性?
只有当组合框项目是所选项目且其基础ID与ItemSource中的最后一个ID匹配时,我才无法使其以红色字体显示。到目前为止,我得到的是,只有当它是选中的项时,它才会变成红色,但我如何检查底层属性“ID”是否与包含它的ObservableCollection中的最后一个条目匹配,即仅当SelectedItem的ID==集合[Length-1].ID时C# 如何仅当WPF ComboBoxItem是选定项且满足条件时才设置其属性?,c#,wpf,xaml,combobox,itemtemplate,C#,Wpf,Xaml,Combobox,Itemtemplate,只有当组合框项目是所选项目且其基础ID与ItemSource中的最后一个ID匹配时,我才无法使其以红色字体显示。到目前为止,我得到的是,只有当它是选中的项时,它才会变成红色,但我如何检查底层属性“ID”是否与包含它的ObservableCollection中的最后一个条目匹配,即仅当SelectedItem的ID==集合[Length-1].ID时 <ComboBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
<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>
因此,如果选择了BillingCycle.ID!=BillingCycles[BillingCycles.Length-1].ID,文本应显示为红色。我不确定如何引用BillingCycles[BillingCycles.Length-1]来进行比较
///编辑:
更改了XAML,这就更接近了,但更改了所有ComboboxItem,而不仅仅是selectedItem。我想我需要使用某种模板选择器,或者完全重新考虑XAML。试试这个:假设我有一个UserType类
public class UserType
{
public string Name { get; set; }
public string Description { get; set; }
}
我将UserType的ObservableCollection绑定到ComboBox的itemsSource
public ObservableCollection<UserType> UserTypes { get; set; }
publicobservableCollection用户类型{get;set;}
xaml
多值转换器
公共类ComboBoxForegroundConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
if(values!=null&&values.Count()=3)
{
var itemsSource=值[0]为ObservableCollection;//这是绑定到itemsSource的集合类型
if(itemsSource!=null&&itemsSource.Any()&&itemsSource.Last()==value[1]&&value[2]==value[1])
返回新的SolidColorBrush(颜色为红色);
}
返回新的SolidColorBrush(颜色为黑色);
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
在您的情况下,DisplayMember路径将是BillingCycleDescription。我最后不得不使用DataTemplateSelector类来区分SelectedItem和其他ComboboxItem:
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;
}
}
公共类ComboBoxItemTemplateSelector:DataTemplateSelector
{
公共数据模板SelectedTemplate{get;set;}
公共数据模板下拉模板{get;set;}
公共覆盖数据模板SelectTemplate(对象项,DependencyObject容器)
{
ComboBoxItem ComboBoxItem=container.GetVisualParent();
如果(comboBoxItem==null)
{
返回所选模板;
}
返回下拉模板;
}
}
这个扩展类:
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;
}
public static T GetVisualParent(此DependencyObject子对象),其中T:Visual
{
while((child!=null)&&&!(child是T))
{
child=visualtreeheloper.GetParent(child);
}
返回子对象作为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>
使用这个转换器,我在Ethicalogics的帮助下找到了它:
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();
}
}
公共类是CurrentCycleColorConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
SolidColorBrush color=新的SolidColorBrush(Colors.Black);
if(values!=null&&values.Count()=2)
{
var itemsSource=值[0]为ObservableCollection;//这是绑定到itemsSource的集合类型
如果(!(itemsSource!=null&&itemsSource.Any()&&itemsSource.First()==(BillingCycle)值[1]))
{
颜色=新的SolidColorBrush(Colors.DarkRed);
}
}
返回颜色;
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
看起来您必须使用转换器
将ID
转换为true
(通过与BillingCycles[BillingCycle.Length-1]进行比较)。ID
(该转换器
用于条件下的绑定)。好的,但是如何指定所选EdItem的ID和ID以及BillingCycles的ID[BillingCycles.Length-1]到转换器?可能我需要两个模板?因为我只希望SelectedItem变为红色,而不希望combobox中的其他项目变为红色?这非常接近,但它会将每个ComboBoxItem变为红色(或黑色)。我如何仅更改SelectedItem(当前选定的ComboBoxItem)的颜色红色?好的,我知道了,但是当选择最后一项时,您希望ComboBox前景为红色吗?我只希望当前SelectedItem的ComboboboxItem将其前景更改为红色,如果它满足var ComboBoxItem的条件,我总是得到null而不是ComboBoxItem,因为值[2]是“{DependencyProperty.UnsetValue}”我已经测试过它工作正常。请确保在最后一次绑定中没有设置任何与Comboboxitem相对应的路径
<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>
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();
}
}