DataGridTemplateColumn中的ComboBox.SelectedItem不绑定到自己的DataGridRow

时间:2013-03-24 00:24:58

标签: c# wpf data-binding datagrid combobox

经过1.5天的头疼,喝咖啡的努力,我终于屈服并呼唤你明智的建议:)。

我在ComboBox DataBinding内发现了很多关于DataGrid TemplateColumn的帖子,但似乎都没有帮助我。

这是我的问题:

我有一个ViewSource对象包含有关Excel列的信息: 列名,列索引和具有数据库列信息的对象。

我的第二个ViewSource是包含数据库列信息的那些对象的列表。

我的目标是在Excel中加载所有WPF DataGrid列,并在列出所有数据库列的每一行中都有ComboBox

当我使用DataGridComboBoxColumn时这很好用,但我不喜欢用户必须单击3次才能打开ComboBox。目前还不是非常明显,无论如何都需要点击它。 (好吧,也许我可以设计它)。

所以我在WPF ComboBox中放置了一个普通的DataGridTemplateColumn,但是所有ComboBox都将SelectedItem绑定到DataGrid.SelectedItem,而不是它们所属的实际行。无论我尝试什么,我都无法做到这一点! :)

    <DataGrid x:Name="ColumnMappings" DataContext="{StaticResource ColumnMappingsViewSource}" ItemsSource="{Binding}" Margin="10,146,10,40" Background="{DynamicResource ControlContainerBackgroundBrush}" BorderBrush="{DynamicResource ControlContainerBorderBrush}" AlternationCount="2" HeadersVisibility="Column" GridLinesVisibility="Horizontal" AutoGenerateColumns="False" SelectionMode="Single" RowBackground="{DynamicResource RowBackGroundBrush}" AlternatingRowBackground="{DynamicResource RowAlternatingBackGroundBrush}" CanUserDeleteRows="False" CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding ColumnName}" ClipboardContentBinding="{x:Null}" Header="Excel Kolom" Width="5*"/>
            <DataGridComboBoxColumn ItemsSource="{Binding Source={StaticResource EntityPropertiesViewSource}}" SelectedItemBinding="{Binding EntityProperty}" DisplayMemberPath="DisplayName" Header="Database Kolom" Width="5*"/>
            <DataGridTemplateColumn Header="Database Kolom" Width="5*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext}"
                                  ItemsSource="{Binding Source={StaticResource EntityPropertiesViewSource}}"
                                  DisplayMemberPath="DisplayName" 
                                  SelectedItem="{Binding EntityProperty}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

1 个答案:

答案 0 :(得分:0)

我想我现在就开始工作了。诀窍是避免为ItemSource使用单独的DataContext ......

     <DataGrid x:Name="ColumnMappings" DataContext="{StaticResource ColumnMappingsViewSource}" ItemsSource="{Binding}" Margin="10,146,10,40" Background="{DynamicResource ControlContainerBackgroundBrush}" BorderBrush="{DynamicResource ControlContainerBorderBrush}" AlternationCount="2" HeadersVisibility="Column" GridLinesVisibility="Horizontal" AutoGenerateColumns="False" SelectionMode="Single" RowBackground="{DynamicResource RowBackGroundBrush}" AlternatingRowBackground="{DynamicResource RowAlternatingBackGroundBrush}" CanUserDeleteRows="False" CanUserAddRows="False" IsReadOnly="True">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding ColumnName}" ClipboardContentBinding="{x:Null}" Header="Excel Kolom" Width="5*"/>
            <DataGridComboBoxColumn ItemsSource="{Binding Source={StaticResource EntityPropertiesViewSource}}" SelectedItemBinding="{Binding EntityProperty}" DisplayMemberPath="DisplayName" Header="Database Kolom" Width="5*"/>
            <DataGridTemplateColumn Header="Database Kolom" Width="5*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding EntityProperties}"
                                  DisplayMemberPath="DisplayName" 
                                  SelectedItem="{Binding EntityProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

唯一的缺点是我的每个ColumMapping对象都需要拥有EntityProperties完整列表的副本:

public class ColumnMapping
{
    public ColumnMapping(string columnName, int columnIndex, EntityProperty entityProperty, List<EntityProperty> entityProperties)
    {
        ColumnName = columnName;
        ColumnIndex = columnIndex;
        EntityProperty = entityProperty;
        EntityProperties = entityProperties;
    }

    public string ColumnName { get; private set; }
    public int ColumnIndex { get; private set; }
    public EntityProperty EntityProperty { get; set; }
    public List<EntityProperty> EntityProperties { get; private set; }
}

public class EntityProperty
{
    public EntityProperty(string displayName, string name)
    {
        DisplayName = displayName;
        Name = name;
    }

    public string DisplayName { get; private set; }
    public string Name { get; private set; }
}

如果有人可能知道更好(更清洁)的解决方案,请告诉我:)