Wpf 组合框SelectedItem初始值不是来自ItemsSource

Wpf 组合框SelectedItem初始值不是来自ItemsSource,wpf,mvvm,binding,combobox,selecteditem,Wpf,Mvvm,Binding,Combobox,Selecteditem,我无法理解组合框的行为 我有一个编辑视图来编辑现有订单数据。以下是我的部分订单数据的虚拟机: public class OrderDataViewModel : ViewModelBase, IOrderDataViewModel { private readonly ICustomersListProviderService _customersListProviderService; private readonly Order _order; public Ord

我无法理解组合框的行为

我有一个编辑视图来编辑现有订单数据。以下是我的部分订单数据的虚拟机:

public class OrderDataViewModel : ViewModelBase, IOrderDataViewModel
{
    private readonly ICustomersListProviderService _customersListProviderService;
    private readonly Order _order;

    public OrderDataViewModel(Order order, ICustomersListProviderService customersListProviderService)
    {
        Assign.IfNotNull(ref _order, order);
        Assign.IfNotNull(ref _customersListProviderService, customersListProviderService);
    }

    public DateTime CreationDate
    {
        get { return _order.CreationDate ?? (_order.CreationDate = DateTime.Now).Value; }
        set
        {
            if (_order.CreationDate == value) return;

            _order.CreationDate = value;
            OnPropertyChanged();
        }
    }

    public Customer Customer
    {
        get { return _order.Customer; }
        set
        {
            if (_order.Customer == value) return;

            _order.Customer = value;
            OnPropertyChanged();
        }
    }


    private IList<Customer> _customersList;
    public IList<Customer> CustomersList
    {
        get { return _customersList ?? (_customersList = _customersListProviderService.GetAllCustomers().ToList()); }
    }
}
现在可以了,但我觉得不太好


有更好的解决方案吗?

也许将SelectedValuePath=“Name”添加到xaml中会有所帮助,如下所示

 <ComboBox Grid.Row="2" Grid.Column="1"
                    SelectedItem="{Binding OrderDataViewModel.Customer}"
                    DisplayMemberPath="Name"
                    ItemsSource="{Binding OrderDataViewModel.CustomersList}"
                    SelectedValuePath="Name"
                    />

创建一个ViewModel,其中包含您需要的两组数据,即设置为填充组合框和记录。为了方便起见,我将使用客户和年份

class CustomerDetailsViewModel
{
    public CustomertModel CutomerModel { get; set; }
    public YearListModel YearList { get; set; }

    public CustomerDetailsViewModel(CustomerModel _CustomerModel)
    {
        CustomerModel = _CustomerModel;
        YearList = new YearListModel();
    }
}
因此,我在组合框中填写了一个年份列表,并且我有我选择的客户记录

<ComboBox x:Name="cbCustomerDetailsYear" Margin="128,503,0,0" 
                      DataContext="{Binding DataContext,
                                    ElementName=CustomerDetailsPage}"
                      ItemsSource="{Binding YearList.Years, Mode=OneWay}"
                      DisplayMemberPath="Description"
                      SelectedValue="{Binding CustomerModel.YearID}"
                      SelectedValuePath="id" />

viewmodel被分配给页面Datacontext,我将其绑定到Combobox

组合框中填充了Itemsource和Displaymember,其中包含my Viewmodel中的年份模型列表。描述只是一个字符串,上面写着1999年、2000年或其他什么

SelectedValue与ViewModel中客户记录中的年份外键绑定。SelectedValuePath是将2绑定在一起的神奇成分。因此,id表示一年的id,但将绑定到customer YearID字段,并由Combobox id值设置


希望这是清楚的

我希望这能奏效:

检查客户是否已绑定到另一个控件。如果是这样,删除所有涉及
Customer
的其他绑定


我遇到了同样的问题,复选框的
IsChecked
属性也绑定到viewModel,但使用转换器检查它是否为null。我将其绑定更改为布尔值,问题不再存在。

您可以覆盖实体中的
Equals()
GetHashCode()
,以及
返回Id.Equals()
Id.GetHashCode()
我刚刚在UWP应用程序中遇到了类似问题。我绑定到一个字符串数组

<ComboBox SelectedItem="{Binding Carrier, Mode=TwoWay}" ItemsSource="{Binding Carriers}" />

在我将ItemsSource更改为SelectedItem之前解决的问题:

<ComboBox ItemsSource="{Binding Carriers}" SelectedItem="{Binding Carrier, Mode=TwoWay}" />


以防有人有类似问题。

您还可以覆盖实体中的
Equals()
GetHashCode()
,并返回
Id.Equals()
Id.GetHashCode()
respectively@HighCore,你的解决方案对我来说是最好的。不幸的是,我不能把它标记为答案,因为它是一个评论。您可以重写它吗?对于需要在组合框中显示不在ItemSource中的值的情况,这是一个非常好的解决方法:
<ComboBox SelectedItem="{Binding Carrier, Mode=TwoWay}" ItemsSource="{Binding Carriers}" />
<ComboBox ItemsSource="{Binding Carriers}" SelectedItem="{Binding Carrier, Mode=TwoWay}" />