如何在Datagrid中绑定ComboBox?

时间:2014-07-21 18:58:10

标签: c# wpf xaml datagrid combobox

我有一个名为groups的表,如下所示:

enter image description here

在查看上图后,我想您可能已经理解主键和外键存在于同一个表中。我认为这就是开发人员所说的循环引用。

在MainWindow.xaml中,我有一个DataGrid,它包含三列,即Group Name,Parent Name,Description。 xaml看起来像:

<Window .......>

    <Window.DataContext>
        <self:MainWindowViewModel />
    </Window.DataContext>

    <DataGrid ItemsSource="{Binding Groups}" TabIndex="1">

        <DataGrid.Columns>

            <DataGridTemplateColumn Header="Group Name" Width="2*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding GroupName}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding GroupName}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Parent" Width="2*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding ParentID}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding DataContext.GroupsCollection, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                                  SelectedValue="{Binding ParentID}"
                                  DisplayMemberPath="GroupName"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Description" Width="2*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Description}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Description}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

        </power:PowerDataGrid.Columns>

    </power:PowerDataGrid>

</Window>

现在我有一个名为MainWindowViewModel

的ViewModel
public class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        SampleDBContext sampleDBContext = new SampleDBContext();
        Groups = new ObservableCollection<Group>();
        GroupsCollection = new ObservableCollection<Group>(from g in sampleDBContext.Groups select g);
    }

    private ObservableCollection<Group> _groups;
    public ObservableCollection<Group> Groups
    {
        get
        {
            return _groups;
        }
        set
        {
            _groups = value;
            OnPropertyChanged("Groups");
        }
    }

    private ObservableCollection<Group> _groupsCollection;
    public ObservableCollection<Group> GroupsCollection
    {
        get
        {
            return _groupsCollection;
        }
        set
        {
            _groupsCollection = value;
            OnPropertyChanged("GroupsCollection");
        }
    }

    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertryName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertryName));
        }
    }

    #endregion
}

问题:

Output :

enter image description here

正如您在上面的图像中看到的,当我在父列中选择一个组后按TAB或Enter时,下一个单元格被聚焦,但是在父列下的单元格有一个红色的轮廓表示一些错误。单元格也不会离开编辑模式。我在输出窗口中也遇到很多绑定错误。所以,我知道我的绑定是不正确的。有人可以帮助我将Combobox绑定到datagrid吗?

更新

如果我使用SelectedValuePath如下:

<ComboBox ItemsSource="{Binding DataContext.GroupsCollection, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
          SelectedValue="{Binding ParentID}" SelectedValuePath="{Binding GroupID}"
          DisplayMemberPath="GroupName" />

然后错误消失,单元格也离开编辑模式。但是TextBlock(这是celltemplate)总是保持空白。

1 个答案:

答案 0 :(得分:0)

解决了它。我不应该在SelectedValuePath中使用Binding。所以,现在我的代码看起来像:

<ComboBox ItemsSource="{Binding DataContext.GroupsCollection, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
          SelectedValue="{Binding ParentID}" SelectedValuePath="GroupID"
          DisplayMemberPath="GroupName" />

现在的问题是:

由于我对CellTemplate的绑定如下所示,在编辑模式完成后,我获得了ComboBox的SelectedValue的ID(但我希望有名称而不是ID):

<DataGridTemplateColumn Header="Parent" Width="2*">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ParentID}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding DataContext.GroupsCollection, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                      SelectedValue="{Binding ParentID}" SelectedValuePath="GroupID"
                      DisplayMemberPath="GroupName" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

所以我创建了一个转换器,如下所示:

public class GroupIDToGroupName : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            SampleDBContext sampleDBContext = new SampleDBContext();
            return (from g in sampleDBContext.Groups
                    where g.GroupID == (int)value
                    select g.GroupName).FirstOrDefault();
        }
        else
        {
            return "";
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        SampleDBContext sampleDBContext = new SampleDBContext();
        return (from g in sampleDBContext.Groups
                where g.GroupName == (string)value
                select g.GroupID).FirstOrDefault();
    }
}

我在App.xaml中将转换器声明为:

<self:GroupIDToGroupName x:Key="GroupIDToGroupNameConveerter" />

现在,我的Cell模板如下所示:

<TextBlock Text="{Binding ParentID, Converter={StaticResource GroupIDToGroupNameConveerter}}" />

我不知道我是否以正确的方式解决了我的问题。但它的工作!!!!

如果有人有个好主意,请分享...........