将DataGridTextComun绑定到DataGridComboBoxColumn.SelectedItem

时间:2016-06-10 18:52:28

标签: c# wpf mvvm datagridcomboboxcolumn datagridtextcolumn

首先让我解释一下我想要的内容,我希望有一个数据网格,其中包含一个ComboBox,可以说是一个公司列表。当我选择一家公司时,我希望它旁边的单元格(DataGridTextColumn)填充公司电话号码。

我能够使用常规的ComboBox和TextBox来做到这一点,但是当我到达Datagrid时,它似乎无法正常工作。下面是我为此示例创建的项目。

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>

公司

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

我不确定我做错了什么。

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

为什么人有公司和公司?公司本身有一个Id属性,无需在Person上复制它。我将从Person中删除CompanyId以获得此答案。

DataGridComboBoxColumn - 摆脱SelectedValuePath =&#34; {Binding CompanyId}&#34;并添加SelectedItemBinding =&#34; {Binding Company,UpdateSourceTrigger = PropertyChanged}&#34;。您选择公司后,UpdateSourceTrigger就会更新电话号码。

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

另一个问题是公司电话DataGridTextColumn。你绑定到元素&#34; ComboBox&#34; (尽管如此,我认为你的意思是&#34; ComboBoxColumn&#34;?)。但这并不是你的想法。它的DataGridComboBoxColumn本身并不是它定义的实例 - 而不是实际的组合框。

您不需要引用组合框,作为行的人对象DataContext具有对公司的引用,因此只需使用它。将公司电话DataGridTextColumn更改为:

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

我希望有所帮助。