在WPF datagrid,combobox模板列上单击编辑

时间:2012-04-24 16:37:14

标签: wpf wpfdatagrid

我有agrid,它有三列:

  1. 友情名称
  2. 大陆名称
  3. 国家/地区名称
  4. 第一列是可编辑的文本框列。第二列是一个显示各大洲列表的Combobox。第3列是组合框,显示基于第2列中选择的大陆的国家列表。我想为这些列实现单击。我尝试了这个链接中给出的解决方案 Single click edit in WPF DataGrid

    但这只适用于第一列,而不适用于其他两列(DataGridTemplateColumn)。

    这怎么可能。请建议。样本XAML和数据描述如下。

    <DataGrid Grid.Row="1" VerticalAlignment="Top"
                                       ItemsSource="{Binding Path=GeographyData,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                      Style="{StaticResource DataGridStyleNormal}">
                                <DataGrid.Columns>
                                    <DataGridTextColumn Width="*" Header="Friendly name" Binding="{Binding Path=FriendlyName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                                    <!--FilterDef -->
                                    <DataGridTemplateColumn Width="*"
                                                            Header="Continents">
                                        <DataGridTemplateColumn.CellEditingTemplate>
                                            <DataTemplate>
                                                <ComboBox SelectedValue="{Binding ContinentId, Mode=TwoWay}"
                                                          SelectedValuePath="ID"
                                                          DisplayMemberPath="Name"
                                                          ItemsSource="{Binding Path=DataContext.ContinentsAndCountries,Mode=OneWay,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}"/>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <TextBlock>
                                                   <TextBlock.Text>
                                                        <MultiBinding Converter="{StaticResource ContinentCaptionConverter}">
                                                              <Binding Path="ContinentId"/>
                                                              <Binding Path="DataContext.ContinentsAndCountries" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}"/>
                                                            </MultiBinding>
                                                    </TextBlock.Text>
                                                </TextBlock>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                    </DataGridTemplateColumn>
                                    <!--Level-->
                                    <DataGridTemplateColumn Width="*"
                                                            Header="Countries">
                                        <DataGridTemplateColumn.CellEditingTemplate>
                                            <DataTemplate>
                                                <ComboBox SelectedValue="{Binding CountryId, Mode=TwoWay}"
                                                          SelectedValuePath="ID"
                                                          DisplayMemberPath="Name">
                                                    <ComboBox.ItemsSource>
                                                        <MultiBinding Converter="{StaticResource CountryValuesConverter}">
                                                            <Binding Path="DataContext.ContinentsAndCountries" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}"/>
                                                            <Binding Path="ContinentId"/>
                                                        </MultiBinding>
                                                    </ComboBox.ItemsSource>
                                                </ComboBox>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellEditingTemplate>
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <TextBlock>
                                                   <TextBlock.Text>
                                                        <MultiBinding Converter="{StaticResource CountryCaptionConverter}">
                                                                <Binding Path="DataContext.ContinentsAndCountries" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}"/>
                                                                <Binding Path="ContinentId"/>
                                                                <Binding Path="CountryId"/>
                                                            </MultiBinding>
                                                    </TextBlock.Text>
                                                </TextBlock>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                    </DataGridTemplateColumn>
                                </DataGrid.Columns>
                            </DataGrid>
    

    注意:数据“ContinentsAndCountries”是主要详细数据的可观察集合。

    • 吉里贾

2 个答案:

答案 0 :(得分:4)

我通过设置组合框加载事件

来做到这一点
private void DataGridComboboxTemplate_Loaded(object sender, RoutedEventArgs e)
    {
        if (sender != null)
        {
            ComboBox cmb = sender as ComboBox;
            cmb.IsDropDownOpen = true;
        }
    }

答案 1 :(得分:1)

对不起他来说我终于想出了如何制作真正的单击UX。您必须拦截DataGridCell的OnGotFocus事件,将单元格模式设置为IsEditing,然后在 CellEditingTemplate 中截取actor控件的Loaded事件:

<Window.Resources>
    <Style
        x:Key="AutoEditModeOnClick"
        TargetType="{x:Type DataGridCell}">

        <EventSetter Event="GotFocus" Handler="DataGridCell_OnGotFocus" />
    </Style>
</Window.Resources>

<DataGrid.Columns>
    <DataGridTemplateColumn
        CellStyle="{StaticResource AutoEditModeOnClick}"
        Header="Score">

        <!-- Example with ComboBox -->

        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <!-- Some more XAML -->
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>

        <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
                <!-- Some more XAML -->
                <ComboBox
                    DisplayMemberPath="Description"
                    SelectedValuePath="RecordID"
                    SelectedValue="{Binding Score,
                        TargetNullValue=0,
                        UpdateSourceTrigger=PropertyChanged}"
                    ItemsSource="{Binding DataContext.ScoreOptions,
                        RelativeSource={RelativeSource
                            AncestorType={x:Type DataGrid}}}"
                    Loaded="Combobox_Loaded"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>

    <DataGridTemplateColumn
        CellStyle="{StaticResource AutoEditModeOnClick}"
        Header="Comment">

        <!-- Example with TextBox -->

        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <!-- Some more XAML -->
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>

        <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
                <!-- Some more XAML -->
                <TextBox
                    Loaded="TextBox_Loaded"
                    Text="{Binding Comment,
                        UpdateSourceTrigger=LostFocus}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

在你的代码隐藏中,你需要三个处理程序;一个用于单元格,一个用于每种类型的控件(ComboBox,TextBox):

    /// <summary>
    /// Skips the 'DataGridCell.Focus' step and goes straight into IsEditing
    /// </summary>
    private void DataGridCell_OnGotFocus(object sender, RoutedEventArgs e)
    {
        DataGridCell cell = sender as DataGridCell;
        cell.IsEditing = true;
    }

    /// <summary>
    /// Skips the 'IsEditing' step and goes straight into IsDropDownOpen
    /// </summary>
    private void Combobox_Loaded(object sender, RoutedEventArgs e)
    {
        ComboBox comboBox = sender as ComboBox;
        comboBox.IsDropDownOpen = true;
    }

    /// <summary>
    /// Skips the 'IsEditing' step and goes straight into Focus
    /// </summary>
    private void TextBox_Loaded(object sender, RoutedEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        textBox.Focus();
    }