2013-07-10 4 views
1

다음 예제에서 텍스트 상자가있을 때 "Billing Model"콤보 상자에 BillingModel.BillingModelDescription 속성이 표시되지 않는 이유를 이해하지 못했습니다. 클라이언트를 선택한 후 콤보 상자에 현재 billng 모델 설명을 표시하고 싶지만 빈 채로 남아 있습니다. 동일한 것에 바인딩 된 텍스트 상자에 설명이 표시됩니다. 나는 잘 작동하는 ItemsSource로서 가능한 모델의 콜렉션을 가지고있다. 클라이언트 선택시 청구 모델 콤보 박스를 업데이트하려면 어떻게해야합니까? 이, 나는 전체 응용 프로그램에서 MVVM 등을 사용하고 단지 예입니다 (WPF ComboBox 항목이 업데이트되지 않는 이유는 무엇입니까?

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

그리고 코드 숨김,하지만이 문제를 설명하기 위해 내 puurpose를 제공 ​​: 여기

는 XAML의) :

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

    } 
} 
+0

하나의 고객에게 하나의 결제 모드가 있습니까? 그런 다음 선택 가능한 콤보 상자로 표시되는 이유는 무엇입니까? 바인딩 된 유형의 결제 모드를 표시하는 간단한 텍스트 상자 일 수 있습니까? – Naresh

+0

@Naresh 각 클라이언트에 대한 청구 모델을 선택해야합니다. – amitfr

+0

@amitfr 그 다음에 그가 의미하는 바는 "고객 선택시 청구 모델 콤보 박스를 어떻게 업데이트합니까?"입니다. 내 생각에, 그는 여러 결제 모드를 가지고 있으며 클라이언트는 옵션 중 몇 가지를 가질 수 있습니까? 나는 무엇인가 놓치고 있습니까? – Naresh

답변

5

내 BillingModelType 클래스에서 Equals()를 재정 의하여이 문제를 해결했습니다. 문제는 제가 생각하기에 BillingModel이 가능한 선택 목록에 사용 된 BillingModel 인스턴스와 완전히 똑같은 것이 아니 었습니다. BillingModelTypes의 클래스에

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

, 모두가 잘 : 그래서 나는 단순히 덧붙였다. Rachel Lim에 대한이 블로그에서이 문제에 대한 블로그를 발견했습니다. http://rachel53461.wordpress.com/2011/08/20/comboboxs-selecteditem-not-displaying/#comments

+0

Rachel은 SelectedValue 및 SelectedValuePath를 사용하여 Item 대신 Value로 SelectedItem을 설정할 수 있다고 제안하지만 올바르게 사용하는 방법을 알지 못했습니다. 아무도 말해 줄 수 있니? –

+1

Hi Theo는'SelectedValue'와'SelectedValuePath'를 사용하기 위해 먼저'SelectedValuePath'를 아이템의 식별자 ('SelectedValuePath = "BillingModelID"')와 같은 문자열로 설정 한 다음 바인드 할 것입니다 (SelectedValue = "{SelectedClient.BillingModelID BindingModelID}"))의 ID에 'SelectedValue'를 추가합니다. 이렇게하려면'SelectedValue = "{Binding SelectedClient.BillingModel.BillingModelID}"'에 바인드하는 것이 올바로 작동하지 않을 것이므로 아마'SelectedClient' 모델을 약간 변경해야 할 것입니다. 나는 잘못 될 수 있으므로 그것을 시도하는 것이 좋습니다. – Rachel

+0

안녕하세요 Rachel,이 모든 작업을하기 위해 SelectedClient를 변경하는 방법은 무엇입니까? 앞에서 언급했듯이 SelectedValue는 SelectedClient.BillingModelID 또는 SelectedClient.BillingModel.BillingModelID에 대한 바인딩과 함께 작동하지 않습니다. 나는 아직도 그것이 존재하는 것처럼 이것이 작동하지 않을 이유를 이해하지 못한다고 생각한다. –

1

나는 당신이 일 것으로 예상 무슨 짓을했는지 모르겠지만, 당신은 AllBillingModels 과금 모델의 모든 (one에 추가three), 그들이 모든 콤보 (평면, 변수 및 무료)에 표시됩니다

편집 : 당신은 아직 여기 경우

OK, 나는을위한 좋은 아이디어
있어 당신의 콤보 상자 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> 

.

+0

예 그들은 콤보 박스에 표시되지만 위의 콤보 박스에서 Employer1을 선택할 때 콤보 상자에서 Employer1이 선택되도록 할당 된 값을 원합니다. Emploer1을 선택하면 combobx에서 "Free"를 선택해야합니다. 당신은 그것이 텍스트 상자에 표시되는 것을 본다 –

+1

@ TheTheoTheSuperCat는 나의 편집되었던 대답을 본다, 나는 그것이 귀여워라고 생각한다. – amitfr

+0

그건 내 예를 위해 일했습니다.내 실제 응용 프로그램에서 텍스트가 콤보 상자에 너무 길면 생략 부호를 표시하기 위해 이미 BillingModelDescription에 바인딩 된 텍스트가 있기 때문에이 솔루션은 작동하지 않습니다.

관련 문제