如何停止WPF Datagridtemplate列退出编辑模式?

时间:2012-05-03 09:30:36

标签: wpf datagrid popup

我正在编写一个MVVM WPF应用程序,其中包含需要可编辑的值的数据网格。值的含义因其他数据而异,因此我编写了一个用户控件,用模板根据值的类型进行编辑。即,它可以显示为文本框,组合框,或链接到数据库以检索可能值的若干其他内部控件之一。 这是我使用的xaml。

<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>

问题是,一旦处于编辑模式,下一次单击ValueEditingControl的任何部分会导致单元格退出编辑模式并返回ValueViewingControl,然后才能实际执行任何操作。 我认为它与细胞有关,认为它失去了焦点。有没有人知道如何保持单元格处于编辑模式,直到我实际标签或单击单元格?

[编辑] 如果我使用文本框或标准组合框作为编辑控件,那么更多测试会告诉我它按预期工作。这让我觉得它是我编写的自定义控件的实现,它包含弹出窗口。当我选择作为编辑控件一部分的弹出窗口时,它认为我已经离开了datagridcell,因此结束了editmode。我如何说服datagridcell弹出窗口是为了集中注意力? 它必须是可能的,否则组合框就无法工作。

2 个答案:

答案 0 :(得分:1)

感谢WPF Popup focus in data grid这个问题,我已经找到了解决自己问题的部分方法 问题似乎是我的弹出窗口浮动的datagridcell试图在我弹出弹出窗口时抓住焦点。
我的解决方案是将此处理程序和帮助程序函数添加到包含弹出窗口的用户控件

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

如果弹出窗口打开,这将停止焦点离开。它并不完美,所以如果有人有更好的解决方案我会全力以赴,但它确实有效。

答案 1 :(得分:0)

如何以这种方式进入编辑模式:

<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>

当不再选择DataGridCell时,编辑模式结束。