WPF数据网格中的单击编辑,组合框模板列

3

我有一个包含三列的网格:

  1. 友好名称
  2. 大陆名称
  3. 国家名称

第一列是可编辑的文本框列。第二列是下拉列表框,显示大陆列表。第三列是下拉列表框,根据在第二列中选择的大陆显示国家列表。我想为这些列实现单击功能。我尝试了此链接中提供的解决方案: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”是一个包含主细节数据的可观察集合。
  • Girija

也许这个答案可以帮助你。 - LPL
不起作用。我猜它做的事情和这个链接里的一样:https://dev59.com/pHA75IYBdhLWcg3wMl8Z - Shankar
我通过设置ComboBox的Loaded事件来实现这一功能private void Combobox_Loaded(object sender, RoutedEventArgs e) { if (sender != null) { ComboBox cmb = sender as ComboBox; cmb.IsDropDownOpen = true; } } - Shankar
2个回答

5
我通过设置下拉框的“Loaded”事件来实现这一点。
private void DataGridComboboxTemplate_Loaded(object sender, RoutedEventArgs e)
    {
        if (sender != null)
        {
            ComboBox cmb = sender as ComboBox;
            cmb.IsDropDownOpen = true;
        }
    }

1

很抱歉打扰了,我终于找到了如何实现真正单击用户体验的方法。您需要拦截DataGridCell的OnGotFocus事件,将单元格模式设置为IsEditing,然后拦截您的CellEditingTemplate中演员控件的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();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接