Xceed DataGrid:使用键盘导航编辑单元格

Posted

技术标签:

【中文标题】Xceed DataGrid:使用键盘导航编辑单元格【英文标题】:Xceed DataGrid: Edit cell with keyboard navigation 【发布时间】:2018-02-23 08:24:04 【问题描述】:

我有一个数据网格,它使用 DataTemplateSelector 将不同的可编辑值显示为文本框、组合框或滑块。问题是我可以制表到这些单元格,但无法用键盘编辑它们。我曾想象一旦单元格被聚焦,我就可以编辑里面的项目。

示例:Tab to textbox-cell > 开始输入 示例:Tab to slider-cell > 现在聚焦 > 使用箭头键编辑

现在我必须用鼠标单击才能开始编辑。无法仅使用键盘开始编辑。

这是我的代码:

    <UserControl.Resources>

    <!--#region DataTemplateSelector-->
    <local:SettingsDataTemplateSelector x:Key="SettingsDataTemplateSelector" />

    <DataTemplate x:Key="TextboxDataTemplate">
        <xcdg:MaskedTextBox IsTabStop="True" Mask="Binding EditMask" Text="Binding EditValue, IsAsync=False, Mode=TwoWay, UpdateSourceTrigger=LostFocus, ValidatesOnExceptions=True"/>
    </DataTemplate>

    <DataTemplate x:Key="ComboDataTemplate">
        <ComboBox IsTabStop="True"  ItemsSource="Binding Path=SelectionValues"
                                    SelectedValuePath="Value"
                                    SelectedValue="Binding Path=SelectionValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"
                                    DisplayMemberPath="ValueText">
        </ComboBox>
    </DataTemplate>

    <DataTemplate x:Key="SliderDataTemplate">
        <Slider IsTabStop="True" Value="Binding EditSliderValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"
                    Minimum="Binding MinRangeValue" 
                    Maximum="Binding MaxRangeValue"
                    VerticalAlignment="Bottom" 
                    IsSnapToTickEnabled="True"
                    TickFrequency="1"
                    Margin="0,0,0,0"/>
    </DataTemplate>
    <!--#endregion-->

    <xcdg:DataGridCollectionViewSource x:Key="Features" 
                                        Source ="Binding Path=Demo.Features"
                                        AutoFilterMode="And"
                                        AutoCreateDetailDescriptions="False" 
                                        AutoCreateItemProperties="False">
        <xcdg:DataGridCollectionViewSource.DetailDescriptions>
            <xcdg:PropertyDetailDescription RelationName="Settings" AutoCreateDetailDescriptions="False" AutoCreateItemProperties="False"/>
        </xcdg:DataGridCollectionViewSource.DetailDescriptions>
    </xcdg:DataGridCollectionViewSource>
</UserControl.Resources>

<Grid>
    <!--#region Xceed DataGrid-->
    <xcdg:DataGridControl x:Name="datagrid"
                          ItemsSource="Binding Source=StaticResource Features"
                          KeyUp="DatagridKeyUp"
                          AllowDetailToggle="True" 
                          Margin="10"
                          NavigationBehavior="RowOrCell" 
                          CellEditorDisplayConditions="RowIsBeingEdited, 
                          MouseOverCell, MouseOverRow, RowIsCurrent, CellIsCurrent" 
                          EditTriggers="BeginEditCommand, ClickOnCurrentCell, 
                          SingleClick, CellIsCurrent, ActivationGesture, RowIsCurrent"
                          ItemScrollingBehavior="Immediate"
                          AutoCreateColumns="False">

        <xcdg:DataGridControl.Resources>
            <Style TargetType="xcdg:TableViewScrollViewer">
                <Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
                <Setter Property="VerticalScrollBarVisibility" Value="Auto" />
            </Style>
        </xcdg:DataGridControl.Resources>

        <xcdg:DataGridControl.View>
            <xcdg:TableflowView UseDefaultHeadersFooters="False" ColumnStretchMode="Last">
                <xcdg:TableflowView.FixedHeaders>
                    <DataTemplate>
                        <xcdg:ColumnManagerRow />
                    </DataTemplate>
                </xcdg:TableflowView.FixedHeaders>
            </xcdg:TableflowView>
        </xcdg:DataGridControl.View>

        <xcdg:DataGridControl.Columns>
            <xcdg:Column FieldName="FeatureID" Title="FeatureID" ReadOnly="True" />
            <xcdg:Column FieldName="Name" Title="Feature name" ReadOnly="True" />
            <xcdg:Column FieldName="Description" Title="Description" ReadOnly="True" />
            <xcdg:Column FieldName=" "/>
        </xcdg:DataGridControl.Columns>

        <xcdg:DataGridControl.DetailConfigurations>
            <xcdg:DetailConfiguration RelationName="Settings" Title="">
                <xcdg:DetailConfiguration.Columns>
                    <xcdg:Column FieldName="Name" Title="Name" ReadOnly="True"/>
                    <xcdg:Column FieldName="Description" Title="Description" ReadOnly="True"/>
                    <xcdg:Column FieldName="EditValues" Title="Edit Values" ReadOnly="True"/>
                    <xcdg:Column FieldName="EditValueVar" Title="Edit Value" Width="150" ReadOnly="False"
                                 CellContentTemplateSelector="StaticResource SettingsDataTemplateSelector"
                                 DisplayMemberBinding="Binding" />
                    <xcdg:Column FieldName=" "/>
                </xcdg:DetailConfiguration.Columns>
            </xcdg:DetailConfiguration>
        </xcdg:DataGridControl.DetailConfigurations>
    </xcdg:DataGridControl>
    <!--#endregion-->
</Grid>

感谢任何帮助。

【问题讨论】:

【参考方案1】:

我最终使用了 Xceed 的 CellEditors。如果您想使用键盘进行编辑,似乎没有办法绕过它们。

将 EditValueVar 列更改为:

                    <xcdg:Column FieldName="EditValueVar" Title="Edit Value" Width="150" ReadOnly="False"
                             CellEditorSelector="StaticResource SettingsCellEditorSelector"/>

注意:已删除 DisplayMemberBinding,因为它可能会导致动态数据出现问题

这是我现在使用的 CellEditor:

    <xcdg:CellEditor x:Key="maskEditor">
    <xcdg:CellEditor.EditTemplate>
        <DataTemplate>
            <xcdg:MaskedTextBox Mask="Binding EditMask"
                                Text="Binding Path=(xcdg:Cell.ParentCell).DataContext.EditValue, 
                                               RelativeSource=RelativeSource Self, 
                                               IsAsync=False, Mode=TwoWay, UpdateSourceTrigger=LostFocus, ValidatesOnExceptions=True"
                                Style="StaticResource x:Type xcdg:MaskedTextBox"/>
            <!--Text="Binding EditValueText, IsAsync=False, Mode=TwoWay, UpdateSourceTrigger=LostFocus, ValidatesOnExceptions=True"/>-->
        </DataTemplate>
    </xcdg:CellEditor.EditTemplate>
    <xcdg:CellEditor.ActivationGestures>
        <xcdg:TextInputActivationGesture />
    </xcdg:CellEditor.ActivationGestures>
</xcdg:CellEditor>

<xcdg:CellEditor x:Key="comboEditor">
    <xcdg:CellEditor.EditTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="Binding Path=(xcdg:Cell.ParentCell).DataContext.SelectionValues, 
                                            RelativeSource=RelativeSource Self, UpdateSourceTrigger=PropertyChanged"
                      SelectedValuePath="Value"
                      SelectedValue="Binding Path=(xcdg:Cell.ParentCell).DataContext.SelectionValue,
                                              RelativeSource=RelativeSource Self, 
                                              UpdateSourceTrigger=PropertyChanged, Mode=TwoWay"
                      DisplayMemberPath="ValueText"
                      Style="StaticResource x:Type ComboBox"
                      ItemContainerStyle="StaticResource x:Type ComboBoxItem"/>
        </DataTemplate>
    </xcdg:CellEditor.EditTemplate>
    <xcdg:CellEditor.ActivationGestures>
        <xcdg:KeyActivationGesture SystemKey="Down"
                                   Modifiers="Alt" />
        <xcdg:KeyActivationGesture Key="Up"
                                   Modifiers="Alt" />
        <xcdg:KeyActivationGesture Key="F4" />
        <xcdg:KeyActivationGesture Key="Space" />
    </xcdg:CellEditor.ActivationGestures>
</xcdg:CellEditor>

<xcdg:CellEditor x:Key="sliderEditor">
    <xcdg:CellEditor.EditTemplate>
        <DataTemplate>
            <Slider Value="Binding Path=(xcdg:Cell.ParentCell).DataContext.EditSliderValue, 
                            RelativeSource=RelativeSource Self, 
                            Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"
                    Minimum="Binding Path=(xcdg:Cell.ParentCell).DataContext.MinRangeValue, RelativeSource=RelativeSource Self"
                    Maximum="Binding Path=(xcdg:Cell.ParentCell).DataContext.MaxRangeValue, RelativeSource=RelativeSource Self"
                    Style="StaticResource x:Type Slider"
                    VerticalAlignment="Bottom" 
                    IsSnapToTickEnabled="True"
                    TickFrequency="1"
                    Margin="0,0,0,0"/>
        </DataTemplate>
    </xcdg:CellEditor.EditTemplate>
    <xcdg:CellEditor.ActivationGestures>
        <xcdg:KeyActivationGesture SystemKey="Right"
                                Modifiers="Alt" />
        <xcdg:KeyActivationGesture Key="Left"
                                Modifiers="Alt" />
        <xcdg:KeyActivationGesture Key="F4" />
        <xcdg:KeyActivationGesture Key="Space" />
    </xcdg:CellEditor.ActivationGestures>
</xcdg:CellEditor>

您可能会注意到奇怪的(xcdg:Cell.ParentCell)-stuff,是的,这很丑陋,但这是合法的做法。改用xcdg:CellEditorBinding 可能会更好。

xcdg:CellEditorBinding 相当于这样的绑定:Binding Path=(xcdg:Cell.ParentCell).Content, Mode=TwoWays, RelativeSource=RelativeSource Self, UpdateSourceTrigger=PropertyChanged

我在内容之前添加了 .DataContext,因为我的数据是结构化的。

希望这对某人有所帮助!

【讨论】:

以上是关于Xceed DataGrid:使用键盘导航编辑单元格的主要内容,如果未能解决你的问题,请参考以下文章

easyui datagrid编辑单元格的时候失去焦点结束编辑代码怎么写

easyui中datagrid合并单元格后,当开启其他列某一个单元格进入编辑状态时,合并行会出现错位,该怎么解决啊

EasyUI DataGrid 编辑单元格

如何观察 DataGrid 的单元格被编辑的事件?

AgGrid 选择单元格编辑器

EasyUI DataGrid 编辑单元格