BeginEdit problem need to be able to select a cell

Jan 13, 2009 at 6:58 PM
Ok i'm trying to set a Edit button outside the datagrid that will trigger the BeginningEdit event of my datagrid.

To do this I set datagrid.BeginEdit() when the user click the button. But every time BeginEdit returns false....

After a lot of debugging i realized that BeginEdit will only works when a cell of the row is selected (and i understand why because when you edit it's usually the content of a cell).

But in my case the row becomes locked when editing.

So that problem is that when i click the Edit button (which is outside the datagrid) I lose the selection of the cell...

So what i want to know is: Is there a way to select any(or a specific) cell from code behind? I don't want to put a "Edit" Button in every row of my datagrid...

thanks
Jan 14, 2009 at 1:38 PM
Edited Jan 14, 2009 at 1:39 PM
Ok i've was able to get it to work with the help of vinsibal previous posts.

So let me post a VB class that extend the datagrid with the Lockable functionnality when the call the method EditButton_Click.

(This is mostly the same code that vinsibal as written, but my class can be used in xaml to create new datagrid that has the Lockable row for edit, a GetRow method and GetCell method)

I really wish that the next release has those functionnality. 

Imports

 

System

 

Imports

 

System.Collections.Generic

 

Imports

 

System.Linq

 

Imports

 

System.Text

 

Imports

 

System.Windows

 

Imports

 

System.Windows.Controls

 

Imports

 

System.Windows.Data

 

Imports

 

System.Windows.Documents

 

Imports

 

System.Windows.Input

 

Imports

 

System.Windows.Media

 

Imports

 

System.Windows.Media.Imaging

 

Imports

 

System.Windows.Navigation

 

Imports

 

System.Windows.Shapes

 

Imports

 

Microsoft.Windows.Controls

 

Imports

 

System.Diagnostics

 

Imports

 

System.Globalization

 

Imports

 

Microsoft.Windows.Controls.Primitives

 

Namespace

 

DataGridSample_LockingRowInEditMode

 

 

''' <summary>

 

 

''' Interaction logic for CustomDataGrid.xaml

 

 

''' </summary>

 

 

Partial Public Class LockableDataGrid

 

 

Inherits DataGrid

 

 

Private _currentEditingRow As DataGridRow

 

 

Public Sub New()

 

 

AddHandler Me.RowEditEnding, AddressOf DataGrid_Standard_RowEditEnding

 

 

AddHandler Me.PreviewKeyDown, AddressOf DataGrid_Standard_PreviewKeyDown

 

 

AddHandler Me.BeginningEdit, AddressOf DataGrid_Standard_BeginningEdit

 

 

End Sub

 

#Region

 

"EditingRow DP"

 

 

Public Property IsEditingRow() As Boolean

 

 

Get

 

 

Return CBool(GetValue(EditingRowProperty))

 

 

End Get

 

 

Set(ByVal value As Boolean)

 

SetValue(EditingRowProperty, value)

 

End Set

 

 

End Property

 

 

''' <summary>

 

 

''' Represents the IsEditing property.

 

 

''' </summary>

 

 

Public Shared ReadOnly EditingRowProperty As DependencyProperty = _

 

DependencyProperty.Register( _

 

"IsEditingRow", GetType(Boolean), _

 

 

GetType(LockableDataGrid), New FrameworkPropertyMetadata(False))

 

#End

 

Region

 

#Region

 

"Editing Events"

 

 

Private Sub DataGrid_Standard_BeginningEdit(ByVal sender As Object, ByVal e As DataGridBeginningEditEventArgs)

 

 

If (Not IsEditingRow) Then

 

 

' set edit mode state

 

IsEditingRow =

True

 

_currentEditingRow = e.Row

 

 

ElseIf (e.Row IsNot _currentEditingRow) Then

 

 

' cancel all new edits for different rows

 

e.Cancel =

True

 

 

End If

 

 

End Sub

 

 

 

Private Sub DataGrid_Standard_PreviewKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)

 

 

Dim row As DataGridRow = GetRow(Me.Items.IndexOf(Me.CurrentItem))

 

 

If (row.IsEditing = False AndAlso e.Key = Windows.Input.Key.Space) Then

 

 

Dim t As Boolean = Me.BeginEdit()

 

 

ElseIf (row.IsEditing AndAlso e.Key = Windows.Input.Key.Enter) Then

 

 

' only 'Enter' key on an editing row will allow a commit to occur

 

IsEditingRow =

False

 

 

End If

 

 

End Sub

 

 

Private Sub DataGrid_Standard_RowEditEnding(ByVal sender As Object, ByVal e As DataGridRowEditEndingEventArgs)

 

 

If (e.EditAction = DataGridEditAction.Cancel) Then

 

 

' cancelling the entire row will reset the state

 

IsEditingRow =

False

 

 

ElseIf (e.EditAction = DataGridEditAction.Commit) Then

 

e.Cancel = IsEditingRow

 

End If

 

 

End Sub

 

#End

 

Region

 

#Region

 

"Functional Events"

 

 

Public Sub EditButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)

 

 

 

 

Me.CurrentCell = New DataGridCellInfo(GetCell(Me.SelectedIndex, 0))

 

 

Dim t As Boolean = Me.BeginEdit()

 

 

End Sub

 

#End

 

Region

 

 

#Region

 

"Helpers"

 

 

Public Function GetCell(ByVal row As Integer, ByVal column As Integer) As DataGridCell

 

 

Dim rowContainer As DataGridRow = GetRow(row)

 

 

If (rowContainer IsNot Nothing) Then

 

 

Dim presenter As DataGridCellsPresenter = CType(GetVisualChild(rowContainer), DataGridCellsPresenter)

 

 

' try to get the cell but it may possibly be virtualized

 

 

Dim cell As DataGridCell = CType(presenter.ItemContainerGenerator.ContainerFromIndex(column), DataGridCell)

 

 

If (cell Is Nothing) Then

 

 

' now try to bring into view and retreive the cell

 

 

Me.ScrollIntoView(rowContainer, Me.Columns(column))

 

cell =

CType(presenter.ItemContainerGenerator.ContainerFromIndex(column), DataGridCell)

 

 

End If

 

 

Return cell

 

 

End If

 

 

Return Nothing

 

 

End Function

 

 

 

 

Public Function GetRow(ByVal index As Integer) As DataGridRow

 

 

Dim row As DataGridRow = CType(Me.ItemContainerGenerator.ContainerFromIndex(index), DataGridRow)

 

 

If (row Is Nothing) Then

 

 

' may be virtualized, bring into view and try again

 

 

Me.ScrollIntoView(Me.Items(index))

 

 

Me.UpdateLayout()

 

row =

CType(Me.ItemContainerGenerator.ContainerFromIndex(index), DataGridRow)

 

 

End If

 

 

Return row

 

 

End Function

 

 

 

Private Overloads Function GetVisualChild(ByVal parent As Visual) As Visual

 

 

Dim child As Visual = Nothing ' = default(T)

 

 

Dim numVisuals As Integer = VisualTreeHelper.GetChildrenCount(parent)

 

 

For i = 0 To numVisuals - 1

 

 

Dim v As Visual = CType(VisualTreeHelper.GetChild(parent, i), Visual)

 

 

If TypeOf v Is DataGridCellsPresenter Then

 

child = v

 

End If

 

 

' child = v 'as T

 

 

If (child Is Nothing) Then

 

child = GetVisualChild(v)

 

End If

 

 

If (child IsNot Nothing) Then

 

 

Exit For

 

 

End If

 

 

Next

 

 

Return child

 

 

End Function

 

 

#End

 

Region

 

 

End Class

 

End

 

Namespace

 

Jan 14, 2009 at 1:40 PM
Sorry for the formating, wish we could insert code snippets