为什么WPF ComboBox项没有更新? [英] Why is WPF ComboBox item not updating?
问题描述
我不理解为什么在我下面的示例在文本框,那么计费模式下拉框不显示属性BillingModel.BillingModelDescription。客户的选择后,我想组合框来显示当前billng模型的描述,但它保持空白。绑定到同一件事的文本框确实显示的说明。我有可能的模式作为的ItemsSource,这是工作的罚款集合。我如何在客户选择更新计费模式组合框?
这里的XAML:
<窗口x:类=WpfApplication7.MainWindow
的xmlns =http://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
标题=主窗口HEIGHT =350WIDTH =525>
<&StackPanel的GT;
< StackPanel的方向=横向>
<标签内容=客户/>
<组合框的ItemsSource ={结合AllClientData}的DisplayMemberPath =EmployerStr
的SelectedItem ={结合SelectedClient}
WIDTH =300/>
< / StackPanel的>
< StackPanel的方向=横向>
<标签内容=计费模式:/>
<组合框的ItemsSource ={结合AllBillingModels}的DisplayMemberPath =BillingModelDescription
的SelectedItem ={结合SelectedClient.BillingModel}
WIDTH =300/>
< / StackPanel的>
< StackPanel的方向=横向>
<标签内容=计费模式/>
<文本框的文本={结合SelectedClient.BillingModel.BillingModelDescription}WIDTH =200/>
< / StackPanel的>
< / StackPanel的>
而code-后面(这只是一个例子,我使用MVVM等在充分应用,但这种服务我puurpose来说明问题):
公共部分类主窗口:窗口,INotifyPropertyChanged的
{
公共主窗口()
{
AllClientData =新的ObservableCollection< ClientRate>();
AllBillingModels =新的ObservableCollection< BillingModelType>(); ClientRate UNO =新ClientRate();
uno.BillingModel =新BillingModelType();
uno.BillingModel.BillingModelID = 3;
uno.BillingModel.BillingModelDescription =自由;
uno.ID = 01;
uno.EmployerName =Employer1; ClientRate DOS =新ClientRate();
dos.BillingModel =新BillingModelType();
dos.BillingModel.BillingModelID = 2;
dos.BillingModel.BillingModelDescription =变量;
dos.ID = 02;
dos.EmployerName =Employer2; ClientRate TRE =新ClientRate();
tre.BillingModel =新BillingModelType();
tre.BillingModel.BillingModelID = 1;
tre.BillingModel.BillingModelDescription =扁平化;
tre.ID = 01;
tre.EmployerName =Employer3; AllClientData.Add(UNO);
AllClientData.Add(DOS);
AllClientData.Add(TRE); BillingModelType 1 =新BillingModelType();
one.BillingModelID = 1;
one.BillingModelDescription =扁平化; BillingModelType 2 =新BillingModelType();
two.BillingModelID = 2;
two.BillingModelDescription =变量; BillingModelType 3 =新BillingModelType();
three.BillingModelID = 3;
three.BillingModelDescription =自由; AllBillingModels.Add(之一);
AllBillingModels.Add(二);
AllBillingModels.Add(三级); 的InitializeComponent();
this.DataContext =这一点;
} 私人的ObservableCollection< ClientRate> _allClientData;
公众的ObservableCollection< ClientRate> AllClientData
{
{返回_allClientData; }
组
{
如果(_allClientData!=值)
{
_allClientData =价值;
FirePropertyChanged(AllClientData);
}
}
} 私人ClientRate _selectedClient;
///<总结>
///获取/设置全局SelectedClient对象
///< /总结>
公共ClientRate SelectedClient
{
{返回_selectedClient; }
组
{
如果(_selectedClient!=值)
{
_selectedClient =价值;
FirePropertyChanged(SelectedClient);
}
}
} //私人BillingModelType _selectedBillingModel;
//公共BillingModelType SelectedBillingModel
// {
//获取
// {
//返回_selectedBillingModel;
//}
//集
// {
//如果(_selectedBillingModel!=值)
// {
// _selectedBillingModel =价值;
// FirePropertyChanged(SelectedBillingModel);
//}
//}
//} 私人的ObservableCollection< BillingModelType> _allBillingModels;
///<总结>
///包含所有可能的计费模式类型
///< /总结>
公众的ObservableCollection< BillingModelType> AllBillingModels
{
{返回_allBillingModels; }
组
{
如果(_allBillingModels!=值)
{
_allBillingModels =价值;
FirePropertyChanged(AllBillingModels);
}
}
} 公共事件PropertyChangedEventHandler的PropertyChanged; 保护无效FirePropertyChanged(字符串propertyName的)
{
如果(的PropertyChanged!= NULL)
的PropertyChanged(这一点,新PropertyChangedEventArgs(propertyName的)); }
}公共类BillingModelType
{
///<总结>
///计费模式ID
///< /总结>
公众诠释? BillingModelID {搞定;组; }
///<总结>
///计费模式说明
///< /总结>
公共字符串BillingModelDescription {搞定;组; }
}公共类ClientRate:INotifyPropertyChanged的
{
///<总结>
///在括号雇主编号雇主名称
///< /总结>
公共字符串EmployerStr {{返回EmployerName +(+ ID +); }}
///<总结>
///雇主ID
///< /总结>
公众诠释? ID {搞定;组; }
私人字符串_EmployerName;
///<总结>
///雇主正式名称
///< /总结>
公共字符串EmployerName
{
{返回_EmployerName; }
组
{
如果(_EmployerName!=值)
{
_EmployerName =价值;
FirePropertyChanged(EmployerName);
}
}
} 私人BillingModelType _billingModel;
///<总结>
///汇率类型标识和说明
///< /总结>
公共BillingModelType BillingModel
{
{返回_billingModel; }
组
{
如果(_billingModel!=值)
{
_billingModel =价值;
FirePropertyChanged(BillingModel);
}
}
} 公共事件PropertyChangedEventHandler的PropertyChanged; 保护无效FirePropertyChanged(字符串propertyName的)
{
如果(的PropertyChanged!= NULL)
的PropertyChanged(这一点,新PropertyChangedEventArgs(propertyName的)); }
}
我通过重写的equals()在我的BillingModelType类解决了这个问题。问题是,我怀疑,那BillingModel是不是在可能的选择列表中使用BillingModel完全相同的实例。所以我只是说:
公共覆盖布尔等于(obj对象)
{
如果(OBJ == NULL ||!(obj是BillingModelType))
返回false;
返回((BillingModelType)OBJ).BillingModelID == this.BillingModelID;
}公共覆盖INT GetHash code()
{
返回this.BillingModelID.GetHash code();
}
到类BillingModelTypes,一切都很好。感谢雷切尔林,因为我发现她的博客在这里对这个问题:
的http://rachel53461.word$p$pss.com/2011/08/20/comboboxs-selecteditem-not-displaying/#comments
I am not understanding why in my following example the "Billing Model" combobox doesn't display the property BillingModel.BillingModelDescription when the textbox does. After selection of a client, i want the combobox to display the current billng model description, but it stays blank. The textbox bound to the same thing does show the description. I have a collection of possible models as the ItemsSource, which is working fine. How do i update the Billing Model combobox upon selection of a client?
Here's the XAML:
<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Client"/>
<ComboBox ItemsSource="{Binding AllClientData}" DisplayMemberPath="EmployerStr"
SelectedItem="{Binding SelectedClient}"
Width="300"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Billing Model:"/>
<ComboBox ItemsSource="{Binding AllBillingModels}" DisplayMemberPath="BillingModelDescription"
SelectedItem="{Binding SelectedClient.BillingModel}"
Width="300"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Billing Model" />
<TextBox Text="{Binding SelectedClient.BillingModel.BillingModelDescription}" Width="200"/>
</StackPanel>
</StackPanel>
And the code-behind (this is just an example, I am using MVVM etc in the full app, but this serves my puurpose to illustrate the issue):
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
AllClientData = new ObservableCollection<ClientRate>();
AllBillingModels = new ObservableCollection<BillingModelType>();
ClientRate uno = new ClientRate();
uno.BillingModel = new BillingModelType();
uno.BillingModel.BillingModelID = 3;
uno.BillingModel.BillingModelDescription = "Free";
uno.ID = 01;
uno.EmployerName = "Employer1";
ClientRate dos = new ClientRate();
dos.BillingModel = new BillingModelType();
dos.BillingModel.BillingModelID = 2;
dos.BillingModel.BillingModelDescription = "Variable";
dos.ID = 02;
dos.EmployerName = "Employer2";
ClientRate tre = new ClientRate();
tre.BillingModel = new BillingModelType();
tre.BillingModel.BillingModelID = 1;
tre.BillingModel.BillingModelDescription = "Flat";
tre.ID = 01;
tre.EmployerName = "Employer3";
AllClientData.Add(uno);
AllClientData.Add(dos);
AllClientData.Add(tre);
BillingModelType one = new BillingModelType();
one.BillingModelID = 1;
one.BillingModelDescription = "Flat";
BillingModelType two = new BillingModelType();
two.BillingModelID = 2;
two.BillingModelDescription = "Variable";
BillingModelType three = new BillingModelType();
three.BillingModelID = 3;
three.BillingModelDescription = "Free";
AllBillingModels.Add(one);
AllBillingModels.Add(two);
AllBillingModels.Add(three);
InitializeComponent();
this.DataContext = this;
}
private ObservableCollection<ClientRate> _allClientData;
public ObservableCollection<ClientRate> AllClientData
{
get { return _allClientData; }
set
{
if (_allClientData != value)
{
_allClientData = value;
FirePropertyChanged("AllClientData");
}
}
}
private ClientRate _selectedClient;
/// <summary>
/// Gets/Sets Global SelectedClient object
/// </summary>
public ClientRate SelectedClient
{
get { return _selectedClient; }
set
{
if (_selectedClient != value)
{
_selectedClient = value;
FirePropertyChanged("SelectedClient");
}
}
}
//private BillingModelType _selectedBillingModel;
//public BillingModelType SelectedBillingModel
//{
// get
// {
// return _selectedBillingModel;
// }
// set
// {
// if (_selectedBillingModel != value)
// {
// _selectedBillingModel = value;
// FirePropertyChanged("SelectedBillingModel");
// }
// }
//}
private ObservableCollection<BillingModelType> _allBillingModels;
/// <summary>
/// Holds all possible billing model types
/// </summary>
public ObservableCollection<BillingModelType> AllBillingModels
{
get { return _allBillingModels; }
set
{
if (_allBillingModels != value)
{
_allBillingModels = value;
FirePropertyChanged("AllBillingModels");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void FirePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class BillingModelType
{
/// <summary>
/// Billing Model ID
/// </summary>
public int? BillingModelID { get; set; }
/// <summary>
/// Billing Model Description
/// </summary>
public string BillingModelDescription { get; set; }
}
public class ClientRate : INotifyPropertyChanged
{
/// <summary>
/// Employer name with Employer ID in parentheses
/// </summary>
public string EmployerStr { get { return EmployerName + " (" + ID + ")"; } }
/// <summary>
/// Employer ID
/// </summary>
public int? ID { get; set; }
private string _EmployerName;
/// <summary>
/// Employer Official Name
/// </summary>
public string EmployerName
{
get { return _EmployerName; }
set
{
if (_EmployerName != value)
{
_EmployerName = value;
FirePropertyChanged("EmployerName");
}
}
}
private BillingModelType _billingModel;
/// <summary>
/// Rate Type ID and Description
/// </summary>
public BillingModelType BillingModel
{
get { return _billingModel; }
set
{
if (_billingModel != value)
{
_billingModel = value;
FirePropertyChanged("BillingModel");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void FirePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
I fixed this problem by overriding Equals() in my BillingModelType class. The problem was, as I suspected, that the BillingModel was not the exact same instance of BillingModel used in the list of possible selections. So I simply added:
public override bool Equals(object obj)
{
if (obj == null || !(obj is BillingModelType))
return false;
return ((BillingModelType)obj).BillingModelID == this.BillingModelID;
}
public override int GetHashCode()
{
return this.BillingModelID.GetHashCode();
}
to the class for BillingModelTypes, and all is well. Credit to Rachel Lim, as i found her blog here about this problem: http://rachel53461.wordpress.com/2011/08/20/comboboxs-selecteditem-not-displaying/#comments
这篇关于为什么WPF ComboBox项没有更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!