1
votes

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.

2
Same as usual. Click the cell to select, click again to enter edit mode. It works fine if I use textboxes instead of my own user controls.PaulMolloy

2 Answers

1
votes

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.

0
votes

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.