1

我正在编写一个 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 弹出窗口在其中以达到焦点目的?它必须是可能的,否则组合框将不起作用。

4

2 回答 2

1

感谢这个问题WPF Popup focus in data grid,我找到了解决我自己问题的部分方法。
问题似乎是当我在弹出窗口中单击时,我的弹出窗口所浮动的数据网格单元试图抢夺焦点。
我的解决方案是将此处理程序和辅助函数添加到包含弹出窗口的用户控件

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

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

于 2012-05-10T14:14:04.267 回答
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不再选择时,编辑模式结束。

于 2012-05-03T14:08:40.377 回答