C# WPF组合框没有';使用ItemContainerGenerator定制时,在第二次打开之前不要更新项目

C# WPF组合框没有';使用ItemContainerGenerator定制时,在第二次打开之前不要更新项目,c#,wpf,xaml,combobox,C#,Wpf,Xaml,Combobox,我试图创建一个带有动态组合框的对话框,该对话框根据其他组合框所选项目的颜色来更改项目文本的颜色。为此,我让combobox的DropDownOpen事件启动一个循环,该循环根据另一个combobox的选定值测试每个comboboxitem的值,并根据其大小更改颜色 它主要使用ComboBox.ItemContainerGenerator直接定制ComboboBox项目,但直到第二次打开ComboBox时才更新颜色 我用更简单的组合框重新创建了这个问题: XAML: C#: 使用系统; 使用S

我试图创建一个带有动态组合框的对话框,该对话框根据其他组合框所选项目的颜色来更改项目文本的颜色。为此,我让combobox的DropDownOpen事件启动一个循环,该循环根据另一个combobox的选定值测试每个comboboxitem的值,并根据其大小更改颜色

它主要使用ComboBox.ItemContainerGenerator直接定制ComboboBox项目,但直到第二次打开ComboBox时才更新颜色

我用更简单的组合框重新创建了这个问题:

XAML:


C#:

使用系统;
使用System.Collections.Generic;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Media;
命名空间可处置XAML
{
公共部分类主窗口:窗口
{
列表intList;
公共主窗口()
{
初始化组件();
DataContext=this;
intList=newlist(){1,2,3,4};
combobox1.ItemsSource=intList;
combobox2.ItemsSource=intList;
}
private void Combobox2DropDownOpen(对象发送方,事件参数e)
{
int SelectedNum=(int)combobox1.SelectedItem;
对于(int i=0;i<4;i++)
{
ComboBoxItem=(ComboBoxItem)combobox2.ItemContainerGenerator.ContainerFromIndex(i);;
如果(项!=null)
{
如果(i
第一次打开时的组合框:

第二个打开的组合框:


有没有办法让组合框在第一次打开时更新?或者有没有更干净的方法可以达到这种效果?

这是一种方法,它主要使用XAML和一个
多值转换器。此示例根据第一个组合框中的选定项目是大于、等于还是小于设置第二个组合框中项目的背景色

MainWindow.xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:ComparisonConverter x:Key="ComparisonConverter" />
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="150" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <ComboBox Name="Box1" ItemsSource="{Binding Items}" Grid.Column="1" Grid.Row="1" />
        <ComboBox Name="Box2" ItemsSource="{Binding Items}" Grid.Column="1" Grid.Row="3">
            <ComboBox.ItemContainerStyle>
                <Style TargetType="ComboBoxItem">
                    <Style.Triggers>
                        <DataTrigger Value="GT">
                            <DataTrigger.Binding>
                                <MultiBinding Converter="{local:ComparisonConverter}">
                                    <Binding ElementName="Box1" Path="SelectedItem" />
                                    <Binding />
                                </MultiBinding>
                            </DataTrigger.Binding>
                            <Setter Property="Background" Value="Red" />
                        </DataTrigger>
                        <DataTrigger Value="LT">
                            <DataTrigger.Binding>
                                <MultiBinding Converter="{local:ComparisonConverter}">
                                    <Binding ElementName="Box1" Path="SelectedItem" />
                                    <Binding />
                                </MultiBinding>
                            </DataTrigger.Binding>
                            <Setter Property="Background" Value="Blue" />
                        </DataTrigger>
                    </Style.Triggers>
                    <Setter Property="Background" Value="Green" />
                </Style>
            </ComboBox.ItemContainerStyle>
        </ComboBox>
    </Grid>
</Window>
using System.Collections.Generic;
using System.Windows;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private List<int> items;

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
            this.items = new List<int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
        }

        public List<int> Items
        {
            get
            {
                return this.items;
            }
        }
    }
}
using System;
using System.Linq;
using System.Windows.Data;
using System.Windows.Markup;

namespace WpfApplication1
{
    public class ComparisonConverter : MarkupExtension, IMultiValueConverter
    {
        public ComparisonConverter()
        {
        }

        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string result = null;
            if (values.Count() >= 2)
            {
                int value1 = System.Convert.ToInt32(values[0]);
                int value2 = System.Convert.ToInt32(values[1]);

                if (value1 > value2)
                {
                    result = "GT";
                }
                else if (value1 < value2)
                {
                    result = "LT";
                }
                else
                {
                    result = "EQ";
                }
            }

            return result;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }
}

MainWindow.xaml.cs:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:ComparisonConverter x:Key="ComparisonConverter" />
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="150" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <ComboBox Name="Box1" ItemsSource="{Binding Items}" Grid.Column="1" Grid.Row="1" />
        <ComboBox Name="Box2" ItemsSource="{Binding Items}" Grid.Column="1" Grid.Row="3">
            <ComboBox.ItemContainerStyle>
                <Style TargetType="ComboBoxItem">
                    <Style.Triggers>
                        <DataTrigger Value="GT">
                            <DataTrigger.Binding>
                                <MultiBinding Converter="{local:ComparisonConverter}">
                                    <Binding ElementName="Box1" Path="SelectedItem" />
                                    <Binding />
                                </MultiBinding>
                            </DataTrigger.Binding>
                            <Setter Property="Background" Value="Red" />
                        </DataTrigger>
                        <DataTrigger Value="LT">
                            <DataTrigger.Binding>
                                <MultiBinding Converter="{local:ComparisonConverter}">
                                    <Binding ElementName="Box1" Path="SelectedItem" />
                                    <Binding />
                                </MultiBinding>
                            </DataTrigger.Binding>
                            <Setter Property="Background" Value="Blue" />
                        </DataTrigger>
                    </Style.Triggers>
                    <Setter Property="Background" Value="Green" />
                </Style>
            </ComboBox.ItemContainerStyle>
        </ComboBox>
    </Grid>
</Window>
using System.Collections.Generic;
using System.Windows;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private List<int> items;

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
            this.items = new List<int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
        }

        public List<int> Items
        {
            get
            {
                return this.items;
            }
        }
    }
}
using System;
using System.Linq;
using System.Windows.Data;
using System.Windows.Markup;

namespace WpfApplication1
{
    public class ComparisonConverter : MarkupExtension, IMultiValueConverter
    {
        public ComparisonConverter()
        {
        }

        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string result = null;
            if (values.Count() >= 2)
            {
                int value1 = System.Convert.ToInt32(values[0]);
                int value2 = System.Convert.ToInt32(values[1]);

                if (value1 > value2)
                {
                    result = "GT";
                }
                else if (value1 < value2)
                {
                    result = "LT";
                }
                else
                {
                    result = "EQ";
                }
            }

            return result;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }
}
使用System.Collections.Generic;
使用System.Windows;
命名空间WpfApplication1
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
私人清单项目;
公共主窗口()
{
初始化组件();
this.DataContext=this;
this.items=新列表(新int[]{0,1,2,3,4,5,6,7,8,9});
}
公共清单项目
{
得到
{
归还此物品;
}
}
}
}
ComparisonConverter.cs:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:ComparisonConverter x:Key="ComparisonConverter" />
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="150" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <ComboBox Name="Box1" ItemsSource="{Binding Items}" Grid.Column="1" Grid.Row="1" />
        <ComboBox Name="Box2" ItemsSource="{Binding Items}" Grid.Column="1" Grid.Row="3">
            <ComboBox.ItemContainerStyle>
                <Style TargetType="ComboBoxItem">
                    <Style.Triggers>
                        <DataTrigger Value="GT">
                            <DataTrigger.Binding>
                                <MultiBinding Converter="{local:ComparisonConverter}">
                                    <Binding ElementName="Box1" Path="SelectedItem" />
                                    <Binding />
                                </MultiBinding>
                            </DataTrigger.Binding>
                            <Setter Property="Background" Value="Red" />
                        </DataTrigger>
                        <DataTrigger Value="LT">
                            <DataTrigger.Binding>
                                <MultiBinding Converter="{local:ComparisonConverter}">
                                    <Binding ElementName="Box1" Path="SelectedItem" />
                                    <Binding />
                                </MultiBinding>
                            </DataTrigger.Binding>
                            <Setter Property="Background" Value="Blue" />
                        </DataTrigger>
                    </Style.Triggers>
                    <Setter Property="Background" Value="Green" />
                </Style>
            </ComboBox.ItemContainerStyle>
        </ComboBox>
    </Grid>
</Window>
using System.Collections.Generic;
using System.Windows;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private List<int> items;

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
            this.items = new List<int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
        }

        public List<int> Items
        {
            get
            {
                return this.items;
            }
        }
    }
}
using System;
using System.Linq;
using System.Windows.Data;
using System.Windows.Markup;

namespace WpfApplication1
{
    public class ComparisonConverter : MarkupExtension, IMultiValueConverter
    {
        public ComparisonConverter()
        {
        }

        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string result = null;
            if (values.Count() >= 2)
            {
                int value1 = System.Convert.ToInt32(values[0]);
                int value2 = System.Convert.ToInt32(values[1]);

                if (value1 > value2)
                {
                    result = "GT";
                }
                else if (value1 < value2)
                {
                    result = "LT";
                }
                else
                {
                    result = "EQ";
                }
            }

            return result;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }
    }
}
使用系统;
使用System.Linq;
使用System.Windows.Data;
使用System.Windows.Markup;
命名空间WpfApplication1
{
公共类比较转换器:MarkupExtension、IMultiValueConverter
{
公共比较转换程序()
{
}
公共对象转换(对象[]值,类型targetType,对象参数,System.Globalization.CultureInfo区域性)
{
字符串结果=null;
if(values.Count()>=2)
{
int value1=System.Convert.ToInt32(值[0]);
int value2=System.Convert.ToInt32(值[1]);
如果(值1>值2)
{
结果=“GT”;
}
否则如果(值1<值2)
{
结果=“LT”;
}
其他的
{
结果=“EQ”;
}
}
返回结果;
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,System.Globalization.CultureInfo区域性)
{
抛出新的NotImplementedException();
}
公共覆盖对象ProviderValue(IServiceProvider服务提供程序)
{
归还这个;
}
}
}

在XAML中,通过使用DataTriggers或类似的方式设置不同的样式,可以更干净地完成此任务。它可能需要一个转换器,具体取决于您的操作方式<带有触发器的XAML中的code>ItemContainerStyle
将是一个更好的选择。对于XAML,这样的事情几乎总是在XAML中完成得最好。