1

我不明白为什么在下面的示例中,“计费模型”组合框在文本框显示时不显示属性 BillingModel.BillingModelDescription。选择客户端后,我希望组合框显示当前的 billng 模型描述,但它保持空白。绑定到同一事物的文本框确实显示了描述。我有一组可能的模型作为 ItemsSource,它工作正常。如何在选择客户端后更新计费模型组合框?

这是 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>

和代码隐藏(这只是一个例子,我在完整的应用程序中使用 MVVM 等,但这有助于我说明问题):

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));

    }
}
4

2 回答 2

7

我通过在 BillingModelType 类中覆盖 Equals() 解决了这个问题。正如我所怀疑的那样,问题在于 BillingModel 与可能选择列表中使用的 BillingModel 实例并不完全相同。所以我简单地补充说:

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();
    }

到 BillingModelTypes 的类,一切都很好。感谢Rachel Lim,因为我在这里找到了她关于这个问题的博客: http ://rachel53461.wordpress.com/2011/08/20/comboboxs-selecteditem-not-displaying/#comments

于 2013-07-10T17:42:41.593 回答
1

我不确定您希望发生什么,但您添加到AllBillingModels所有计费模型 ( one two three),它们都显示在组合框中(平面、可变和免费)

编辑:

好的,如果您还在这里,我
对您的 ComboBox Xaml 有一个好主意:

<StackPanel Orientation="Horizontal">
        <Label Content="Billing Model:"/>
        <ComboBox ItemsSource="{Binding AllBillingModels}" DisplayMemberPath="BillingModelDescription"
          SelectedItem="{Binding SelectedClient.BillingModel}"
                  Text="{Binding SelectedClient.BillingModel.BillingModelDescription}"
          Width="300"/>
</StackPanel>

这将更新组合框中的测试。

于 2013-07-10T14:36:51.910 回答