2016-06-10 21 views
0

Lassen Sie mich zuerst erklären, was ich will, ich hätte gerne ein Datagrid, das eine ComboBox haben wird, sagen wir eine Liste von Unternehmen. Wenn ich eine Firma wähle, möchte ich die Zelle (DataGridTextColumn) daneben, um die Firma Telefonnummer zu füllen.Ein DataGridTextComun an DataGridComboBoxColumn.SelectedItem binden

Ich konnte dies mit einer regulären ComboBox und TextBox tun, aber wenn ich zu einem Datagrid komme, scheint es nicht richtig zu funktionieren. Unten ist das Projekt, das ich für dieses Beispiel erstellt habe.

enter image description here

 <DataGrid Grid.Row="3" 
       Grid.Column="0" 
       Grid.ColumnSpan="2" 
       ItemsSource="{Binding People}" 
       AutoGenerateColumns="False"> 
     <DataGrid.Columns> 
      <DataGridComboBoxColumn Header="Comapny" 
            x:Name="ComboBoxColumn" 
            SelectedValuePath="{Binding CompanyId}" 
            DisplayMemberPath="Name"> 
       <DataGridComboBoxColumn.ElementStyle> 
        <Style TargetType="{x:Type ComboBox}"> 
         <Setter Property="ItemsSource" 
           Value="{Binding Path=DataContext.Companies, 
          RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
        </Style> 
       </DataGridComboBoxColumn.ElementStyle> 
       <DataGridComboBoxColumn.EditingElementStyle> 
        <Style TargetType="{x:Type ComboBox}"> 
         <Setter Property="ItemsSource" 
           Value="{Binding Path=DataContext.Companies, 
          RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
         <Setter Property="IsEditable" 
           Value="True" /> 
         <Setter Property="SelectedItem" 
           Value="{Binding Path=DataContext.Company}"/> 
        </Style> 
       </DataGridComboBoxColumn.EditingElementStyle> 
      </DataGridComboBoxColumn> 
      <DataGridTextColumn Header="Company Phone" 
           Binding="{Binding ElementName=ComboBox, 
       Path=SelectedItem.Phone, 
       UpdateSourceTrigger=PropertyChanged}"/> 
      <DataGridTextColumn Header="Person Name" 
           Binding="{Binding Name}" /> 
     </DataGrid.Columns> 
    </DataGrid> 

Firma:

{ 
    private string _name; 
    private string _phone; 
    public int Id { get; set; } 

    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      if(_name!=value) 
      { 
       _name = value; 
       OnPropertyChanged(); 
      } 
     } 
    } 
    public string Phone 
    { 
     get { return _phone; } 
     set 
     { 
      if (_phone != value) 
      { 
       _phone = value; 
       OnPropertyChanged(); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 

Person:

public class Person:INotifyPropertyChanged 
{ 
    private Company _company; 
    private int _companyId; 
    private string _name; 
    public int Id { get; set; } 

    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      if (_name != value) 
      { 
       _name = value; 
      } 
     } 
    } 

    public Company Company 
    { 
     get { return _company; } 
     set 
     { 
      if (_company != value) 
      { 
       _company = value; 
       OnPropertyChanged(); 
      } 
     } 
    } 

    public int CompanyId 
    { 
     get { return _companyId; } 
     set 
     { 
      if (_companyId != value) 
      { 
       _companyId = value; 
       OnPropertyChanged(); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

Ich bin nicht sicher, was ich falsch mache.

Dank für Ihre Hilfe

Antwort

1

Warum hat Person Unternehmen und CompanyID? Das Unternehmen selbst verfügt über eine Id-Eigenschaft, sodass es nicht auf Person repliziert werden muss. Ich werde CompanyId von Person für diese Antwort entfernen.

DataGridComboBoxColumn - loswerden von SelectedValuePath = "{Binding CompanyId}" und fügen Sie SelectedItemBinding = "{Binding Company, UpdateSourceTrigger = PropertyChanged}" hinzu. Der UpdateSourceTrigger ist so, dass die Telefonnummer aktualisiert wird, sobald Sie eine Firma auswählen.

<DataGridComboBoxColumn Header="Company" 
        x:Name="ComboBoxColumn" 
        SelectedItemBinding="{Binding Company, UpdateSourceTrigger=PropertyChanged}" 
        DisplayMemberPath="Name"> 

Das andere Problem ist mit der Firma Phone DataGridTextColumn. Sie binden an das Element "ComboBox" (obwohl Sie "ComboBoxColumn" meinen?). Aber das ist nicht das, was du denkst. Es ist die DataGridComboBoxColumn selbst keine Instanz dessen, was es definiert - nicht die eigentliche Combobox.

Sie müssen nicht auf die Combobox verweisen, das Personenobjekt, das DataContext der Zeile ist, hat einen Verweis auf das Unternehmen, also verwenden Sie es einfach. Ändern Sie die Firma Phone DataGridTextColumn zu diesem:

<DataGridTextColumn Header="Company Phone" Binding="{Binding Path=Company.Phone, UpdateSourceTrigger=PropertyChanged}"/> 

Ich hoffe, dass das hilft.

+0

Vielen Dank. Das hilft! – JamTay317