C# 如何仅当WPF ComboBoxItem是选定项且满足条件时才设置其属性?

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"

只有当组合框项目是所选项目且其基础ID与ItemSource中的最后一个ID匹配时,我才无法使其以红色字体显示。到目前为止,我得到的是,只有当它是选中的项时,它才会变成红色,但我如何检查底层属性“ID”是否与包含它的ObservableCollection中的最后一个条目匹配,即仅当SelectedItem的ID==集合[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>

因此,如果选择了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();
    }
}