我无法理解组合框的行为。
我有一个编辑视图来编辑现有的订单数据。这是订单数据某些部分的VM:
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()); }
}
}
和XAML绑定:
<ComboBox Grid.Row="2" Grid.Column="1"
SelectedItem="{Binding OrderDataViewModel.Customer}"
DisplayMemberPath="Name"
ItemsSource="{Binding OrderDataViewModel.CustomersList}"
/>
描述。订单来自Repository的数据库,_customersListProviderService也从数据库中获取所有客户。我知道也许它可以做得更好,但这不是问题的关键。
而且......问题是。加载窗口后,我的组合框已填充项目集合(下拉列表不为空)但未设置该值(其空白)。通过代码隐藏结果检查SelectedItem为null。我读了很多,发现你不能将组合框的SelectedItem设置为不在ItemsSource中的项目。
好的,我的解决方法是将Customer getter更改为:
public Customer Customer
{
get
{ return CustomersList.Single(c => c.Id == _order.Customer.Id); }
set
{
if (_order.Customer == value) return;
_order.Customer = value;
OnPropertyChanged();
}
}
现在它有效,但对我来说看起来不太好。
有没有更好的解决方案?
答案 0 :(得分:4)
您可以覆盖实体中的Equals()
和GetHashCode()
以及return Id.Equals()
和Id.GetHashCode()
答案 1 :(得分:2)
我在 UWP应用中遇到了类似的问题。我绑定了一个字符串数组。
<ComboBox SelectedItem="{Binding Carrier, Mode=TwoWay}" ItemsSource="{Binding Carriers}" />
当我将ItemsSource更改为SelectedItem:
之前,问题解决了<ComboBox ItemsSource="{Binding Carriers}" SelectedItem="{Binding Carrier, Mode=TwoWay}" />
以防万一有类似问题。
答案 2 :(得分:0)
或许将SelectedValuePath =“Name”添加到您的xaml(如下所示)将有助于
<ComboBox Grid.Row="2" Grid.Column="1"
SelectedItem="{Binding OrderDataViewModel.Customer}"
DisplayMemberPath="Name"
ItemsSource="{Binding OrderDataViewModel.CustomersList}"
SelectedValuePath="Name"
/>
答案 3 :(得分:0)
使用您需要的两组数据创建一个ViewModel,即设置为填充ComboBox和Record。为方便起见,我将使用客户和年份。
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分配给Page Datacontext,然后将其绑定到Combobox。
使用我的Viewmodel中的Year model列表,使用Itemsource和Displaymember填充组合框。描述只是一个字符串,说1999年,2000年或其他什么
SelectedValue也绑定到ViewModel中Customer记录中的Year外键。 SelectedValuePath是将2绑定在一起的神奇成分。因此id表示年份的id,但将绑定到客户YearID字段并由Combobox id值设置。
希望这很清楚?!?!?!
答案 4 :(得分:0)
我希望这会奏效:
检查Customer
是否已绑定到另一个控件。如果是这样,会删除涉及Customer
的所有其他绑定。
我遇到了同样的问题,其中CheckBox的IsChecked
属性也被绑定到viewModel,但是使用转换器检查它是否为null。我将其绑定更改为布尔值,问题就不复存在了。