【问题标题】:Combobox with two itemssources具有两个项目源的组合框
【发布时间】:2026-01-08 09:55:02
【问题描述】:

我正在尝试根据单选按钮列出客户或供应商。当我将一个列表绑定到组合框时,它可以工作。当我尝试使用数据触发器动态更改要显示的集合时,没有任何反应。

由于单独的列表与不变的组合框一起使用,我已经知道这不是数据上下文类型的问题。我还安装了 Fody Weaver 来自动生成 INotifyProperties。

XAML:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <RadioButton Content="Klant"
                 Grid.Column="0"
                 Foreground="White"
                 Margin="10"
                 IsChecked="{Binding ButtonCustomerIsChecked}"
                 GroupName="CustomerSupplier"
                 Name="RadioButtonCustomer"
                 />
    <RadioButton Content="Leverancier"
                 Grid.Column="1"
                 Foreground="White"
                 Margin="10"
                 IsChecked="{Binding ButtonSupplierIsChecked}"
                 GroupName="CustomerSupplier"
                 Name="RadioButtonSupplier"
                 />
</Grid>

<ComboBox ItemsSource="{Binding SupplierList}"
          DisplayMemberPath="Name"
          SelectedItem="{Binding Path=SelectedCustomerSupplier}"
          Style="{StaticResource InputComboBox}"
          />

<ComboBox Style="{StaticResource InputComboBox}"
          ItemsSource="{Binding}"
          DisplayMemberPath="Name"
          >
    <Style TargetType="{x:Type ComboBox}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsChecked, ElementName=ButtonCustomerIsChecked, diag:PresentationTraceSources.TraceLevel=High}"  Value="True">
                <Setter Property="ItemsSource" Value="{Binding CustomerList}"/>
            </DataTrigger>

            <DataTrigger Binding="{Binding IsChecked, ElementName=ButtonSupplierIsChecked, diag:PresentationTraceSources.TraceLevel=High}" Value="True">
                <Setter Property="ItemsSource" Value="{Binding SupplierList}"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ComboBox>

C#(视图模型):

CustomerList = new ObservableCollection<Customer>
{
    new Customer{Id=1, Name="Bart"},
    new Customer{Id=1, Name="Nick"},
    new Customer{Id=1, Name="Erwin"},
};

SupplierList = new ObservableCollection<Customer>
{
    new Customer{Id=1, Name="Rita"},
    new Customer{Id=1, Name="Sascha"},
    new Customer{Id=1, Name="Didier"},
};

更多C#(客户类):

public class Customer : IStakeholder
{
    /// <summary>
    /// The ID of the customer
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// The name of the customer
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// The phone number
    /// </summary>
    public string PhNr { get; set; }

    /// <summary>
    /// The VAT number
    /// can be null
    /// </summary>
    public string VatNr { get; set; }

    /// <summary>
    /// The country where the customer is located
    /// </summary>
    public CountryCat CountryCat { get; set; }

    /// <summary>
    /// A list of payments made by the customer
    /// </summary>
    public List<IPayments> Payments { get; set; }
}

【问题讨论】:

  • 您更有可能遇到value precedence 问题,将初始属性分配移动到样式设置器中。
  • 您能详细说明一下吗?我对 XAML/C# 还很陌生,我不确定您指的是哪个初始属性分配。

标签: c# wpf combobox datatrigger itemssource


【解决方案1】:

代替

<ComboBox ItemsSource="{Binding SupplierList}" ...>
    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}">
            <Style.Triggers>
                <DataTrigger ...>
                    <Setter Property="ItemsSource" Value="{Binding CustomerList}"/>
                </DataTrigger>
            </Style.Triggers>
        <Style>
    <ComboBox.Style>
</ComboBox>

您必须将 ItemsSource 的初始分配移动到如下样式设置器中:

<ComboBox ...>
    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}">
            <Style.Setters>
                <Setter Property="ItemsSource" Value="{Binding SupplierList}" />
            </Style.Setters>
            <Style.Triggers>
                <DataTrigger ...>
                    <Setter Property="ItemsSource" Value="{Binding CustomerList}"/>
                </DataTrigger>
            </Style.Triggers>
        <Style>
    <ComboBox.Style>
</ComboBox>

否则样式触发器不能覆盖本地值,见dependency property value precedence


另一个问题是您绑定到视图中的特定元素的样式是什么,这使得它不太可重用,您会看到您必须创建与您拥有的单选按钮一样多的数据触发器.此外,您在那里的绑定中使用了错误的ElementName,例如不是ButtonCustomerIsChecked,应该是RadioButtonCustomer(供应商也一样)。

这是一个修复,您只需要一个触发器:

 <Style.Triggers>
     <DataTrigger Binding="{Binding IsChecked, ElementName=RadioButtonCustomer}" Value="True">
         <Setter Property="ItemsSource" Value="{Binding CustomerList}"/>
     </DataTrigger>
 </Style.Triggers>

更好的方法是在 ViewModel 中提供一个属性(它是 MVVM 术语,viewmodel 是一个定义了CustomerList 的类),它将用于运行触发器。

或者更简单的方法是更改​​视图模型中绑定到ItemsSource 的单个属性,这样您就不需要视图中的触发器了。

【讨论】:

  • &lt;Style.Setters&gt; 是多余的。
  • 感谢您的快速回复。我已经更新了我的代码,但我只得到了初始列表,它是在您的 之间设置的。因此,当我按下其中一个单选按钮时,列表还没有改变。
  • @Clemens,谢谢,在与 wpf /facepalm 合作 3 年后很高兴知道。
  • @BartPinnock,还有更多问题,请参阅编辑。通常你应该观察输出窗口中的绑定错误,然后我猜你会自己意识到这一点。
  • @Sinatr 谢谢!
最近更新 更多