将 DataGridTextComun 绑定到 DataGridComboBoxColumn.SelectedItem
Binding a DataGridTextComun To DataGridComboBoxColumn.SelectedItem
让我先解释一下我想要什么,我想要一个数据网格,它有一个组合框,可以说是一个公司列表。当我选择一家公司时,我希望它旁边的单元格 (DataGridTextColumn) 填充公司 phone 编号。
我能够使用常规的 ComboBox 和 TextBox 执行此操作,但是当我使用 Datagrid 时,它似乎无法正常工作。下面是我为此示例创建的项目。
<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>
公司:
{
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));
}
人:
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));
}
}
我不确定我做错了什么。
感谢您的帮助
为什么 Person 有 Company 和 CompanyId? Company本身就有一个Id属性,不需要复制到Person上。对于此答案,我将从 Person 中删除 CompanyId。
DataGridComboBoxColumn - 删除 SelectedValuePath="{Binding CompanyId}" 并添加 SelectedItemBinding="{Binding Company, UpdateSourceTrigger=PropertyChanged}"。 UpdateSourceTrigger 因此 phone 数字会在您选择公司后立即更新。
<DataGridComboBoxColumn Header="Company"
x:Name="ComboBoxColumn"
SelectedItemBinding="{Binding Company, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name">
另一个问题与公司 Phone DataGridTextColumn 有关。您绑定到元素 "ComboBox"(尽管我认为您的意思是 "ComboBoxColumn"?)。但那不是你想的那样。它是 DataGridComboBoxColumn 本身,而不是它定义的实例 - 不是实际的组合框。
您不需要引用组合框,作为行的 DataContext 的人员对象引用了公司,因此只需使用它即可。将公司 Phone DataGridTextColumn 更改为:
<DataGridTextColumn Header="Company Phone" Binding="{Binding Path=Company.Phone, UpdateSourceTrigger=PropertyChanged}"/>
希望对您有所帮助。
让我先解释一下我想要什么,我想要一个数据网格,它有一个组合框,可以说是一个公司列表。当我选择一家公司时,我希望它旁边的单元格 (DataGridTextColumn) 填充公司 phone 编号。
我能够使用常规的 ComboBox 和 TextBox 执行此操作,但是当我使用 Datagrid 时,它似乎无法正常工作。下面是我为此示例创建的项目。
<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>
公司:
{
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));
}
人:
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));
}
}
我不确定我做错了什么。
感谢您的帮助
为什么 Person 有 Company 和 CompanyId? Company本身就有一个Id属性,不需要复制到Person上。对于此答案,我将从 Person 中删除 CompanyId。
DataGridComboBoxColumn - 删除 SelectedValuePath="{Binding CompanyId}" 并添加 SelectedItemBinding="{Binding Company, UpdateSourceTrigger=PropertyChanged}"。 UpdateSourceTrigger 因此 phone 数字会在您选择公司后立即更新。
<DataGridComboBoxColumn Header="Company"
x:Name="ComboBoxColumn"
SelectedItemBinding="{Binding Company, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name">
另一个问题与公司 Phone DataGridTextColumn 有关。您绑定到元素 "ComboBox"(尽管我认为您的意思是 "ComboBoxColumn"?)。但那不是你想的那样。它是 DataGridComboBoxColumn 本身,而不是它定义的实例 - 不是实际的组合框。
您不需要引用组合框,作为行的 DataContext 的人员对象引用了公司,因此只需使用它即可。将公司 Phone DataGridTextColumn 更改为:
<DataGridTextColumn Header="Company Phone" Binding="{Binding Path=Company.Phone, UpdateSourceTrigger=PropertyChanged}"/>
希望对您有所帮助。