How do I stop a WPF Datagridtemplatecolumn from exiting edit mode?

社会主义新天地 提交于 2019-12-23 03:52:17

问题


I'm writing an MVVM WPF app with a datagrid of values which needs to be editable. The meaning of the value varies depending on other data, so I've written a usercontrol for editing them with a template that varies depending on the type of value. i.e. it may appear as a textbox, a combobox, or one of several other inhouse controls that link to databases to retrieve possible values. This is the xaml I've used.

<DataGridTemplateColumn Header="Value">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <local:ValueViewingControl Value="{Binding Value}" ValueType="{Binding SettingValueType}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <local:ValueEditingControl Value="{Binding Value,Mode=TwoWay}" ValueType="{Binding SettingValueType}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

The problem is that once in editing mode, the next click on any part of the ValueEditingControl causes the cell to exit edit mode and go back to the ValueViewingControl before I can actually do anything. I assume its something to do with the cell thinking its lost focus. Does anyone know a way of keeping the cell in edit mode until I actually tab or click out of the cell?

[edit] A little more testing shows me that it works as expected if I use a textbox or a standard combobox as the edit control. This is making me think its the implementation of the custom controls I've written, which incorporate popups. When I select the popup that is part of the editing control, it thinks I've left the datagridcell and so ends editmode. How do I convince the datagridcell that the popup is inside it for focus purposes? It must be possible or the combobox wouldnt work.


回答1:


Thanks to this question WPF Popup focus in data grid , I've figured out a partial solution to my own problem.
The problem seems to be that the datagridcell over which my popups are floating is trying to snatch the focus when I click inside my popups.
My solution is to add this handler and helper function to the usercontrol containing the popup

Private Sub ControlRoot_PreviewLostKeyboardFocus(sender As System.Object, e As System.Windows.Input.KeyboardFocusChangedEventArgs)
    Dim popupelement As Popup = FindVisualChild(Of Popup)(ControlRoot)
    If (popupelement IsNot Nothing AndAlso popupelement.IsOpen) Then
        e.Handled = True
    End If
End Sub

Function FindVisualChild(Of T As DependencyObject)(ByVal element As DependencyObject) As T
    If element Is Nothing Then
        Return Nothing
    ElseIf TypeOf (element) Is T Then
        Return element
    Else
        Dim count = VisualTreeHelper.GetChildrenCount(element)
        For index As Integer = 0 To count - 1
            Dim child As DependencyObject = VisualTreeHelper.GetChild(element, index)
            If TypeOf (child) Is T Then
                Return child
            Else
                Dim grandchild As T = FindVisualChild(Of T)(child)
                If grandchild IsNot Nothing Then Return grandchild
            End If
        Next
    End If
    Return Nothing
End Function

This stops the focus from leaving if the popup is open. It's not perfect, so if anyone has a better solution I'm all ears, but it works.




回答2:


How about to enter edit mode this way:

<DataGrid.CellStyle>
    <Style TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="IsEditing" Value="True" />
            </Trigger>
        </Style.Triggers>
    </Style>
</DataGrid.CellStyle>

Edit mode ends when DataGridCell is no more selected.



来源:https://stackoverflow.com/questions/10428636/how-do-i-stop-a-wpf-datagridtemplatecolumn-from-exiting-edit-mode

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!