Imports DevExpress.Xpf.Grid.Native Imports DevExpress.Xpf.Grid 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.Shapes Imports DevExpress.Xpf.Core Imports DevExpress.Xpf.Bars Imports DevExpress.Xpf.Printing Imports System.ComponentModel Imports System.Collections.ObjectModel Imports System.Collections Imports DevExpress.Xpf.Core.Serialization Imports DevExpress.Data Imports tsUtilidades.Extensiones Imports System.Globalization Public Class tsGridControl Inherits DevExpress.Xpf.Grid.GridControl Public ElementosSeleccionados As ObservableCollectionCore(Of Object) Public Property PopupFilterModeInicializado As Boolean Public ReadOnly Property MySelectedItems() As IList Get Return ElementosSeleccionados End Get End Property Private _NombreTablaBase As String Public Property PropiedadesTS As New PropiedadesTS Public Property PropiedadesTSGC As New PropiedadesTSGC Public Sub EstableceSoloLectura(Optional SoloLectura As Boolean = True) For Each c In Me.Columns If c.CellTemplate Is Nothing Then c.ReadOnly = SoloLectura Else c.AllowEditing = If(SoloLectura, DevExpress.Utils.DefaultBoolean.False, DevExpress.Utils.DefaultBoolean.True) End If Dim bes = TryCast(c.EditSettings, DevExpress.Xpf.Editors.Settings.ButtonEditSettings) If bes IsNot Nothing Then bes.AllowDefaultButton = Not SoloLectura For Each bt In bes.Buttons bt.IsEnabled = Not SoloLectura Next End If Next If Not Me.ContextMenu Is Nothing AndAlso Me.ContextMenu.HasItems Then Dim mi As MenuItem = Me.ContextMenu.Items(0) mi.IsEnabled = Not SoloLectura End If End Sub Public Sub ReEstableceValoresDefectoSoloLectura() For Each c In Me.Columns If c.CellTemplate Is Nothing Then If c.GetType Is GetType(tsGridColumn) Then c.ReadOnly = DirectCast(c, tsGridColumn).SoloLectura Dim bes = TryCast(c.EditSettings, DevExpress.Xpf.Editors.Settings.ButtonEditSettings) If bes IsNot Nothing Then bes.AllowDefaultButton = Not c.ReadOnly For Each bt In bes.Buttons bt.IsEnabled = Not c.ReadOnly Next End If Else c.ReadOnly = False End If Else If c.GetType Is GetType(tsGridColumn) Then If DirectCast(c, tsGridColumn).SoloLectura Then If c.CellTemplate Is Nothing Then c.ReadOnly = True Else c.AllowEditing = DevExpress.Utils.DefaultBoolean.False End If Dim bes = TryCast(c.EditSettings, DevExpress.Xpf.Editors.Settings.ButtonEditSettings) If bes IsNot Nothing Then bes.AllowDefaultButton = False For Each bt In bes.Buttons bt.IsEnabled = False Next End If Else c.AllowEditing = DevExpress.Utils.DefaultBoolean.True Dim bes = TryCast(c.EditSettings, DevExpress.Xpf.Editors.Settings.ButtonEditSettings) If bes IsNot Nothing Then bes.AllowDefaultButton = True For Each bt In bes.Buttons bt.IsEnabled = True Next End If End If Else If c.CellTemplate Is Nothing Then c.ReadOnly = True Else c.AllowEditing = DevExpress.Utils.DefaultBoolean.False End If End If End If Next End Sub Public Property NombreTablaBase As String Get Return _NombreTablaBase End Get Set(value As String) _NombreTablaBase = value End Set End Property Public Event AntesEliminar(ByVal gc As tsGridControl, ByRef Cancelar As Boolean) Public Event DespuesEliminar(ByVal gc As tsGridControl) Public Event EnterPulsado() Public Event SeleccionCambiada(ByVal gc As tsGridControl, e As GridSelectionChangedEventArgs) Public Event AntesExportar(ByVal gc As tsGridControl, ByRef Cancelar As Boolean) Property ComandoDelegado As DevExpress.Mvvm.DelegateCommand(Of Object) Friend Function LanzaAntesExportar(gc As tsGridControl) As Boolean Dim Cancelar As Boolean RaiseEvent AntesExportar(gc, Cancelar) Return Cancelar End Function Friend Function LanzaAntesEliminar(gc As tsGridControl) As Boolean Dim Cancelar As Boolean RaiseEvent AntesEliminar(gc, Cancelar) Return Cancelar End Function Friend Function LanzaDespuesEliminar(gc As tsGridControl) As Boolean Dim Cancelar As Boolean RaiseEvent DespuesEliminar(gc) Return Cancelar End Function Friend Function LanzaEnterPulsado() As Boolean Dim Cancelar As Boolean RaiseEvent EnterPulsado() Return Cancelar End Function Public Sub New() MyBase.New() End Sub Private NumeroColumnasAgrupadas As Integer Friend Sub MyGridControl_StartGrouping(sender As Object, e As RoutedEventArgs) updateLocker.Lock() End Sub Public Function ObtieneNumeroColumnasAgrupadas() As Integer Return Me.Columns.Where(Function(x) x.IsGrouped).Count End Function Friend Sub MyGridControl_EndGrouping(sender As Object, e As RoutedEventArgs) 'Dim nca = ObtieneNumeroColumnasAgrupadas() 'Dim bDesAgrupando As Boolean = NumeroColumnasAgrupadas > nca 'NumeroColumnasAgrupadas = nca 'If bDesAgrupando Then updateLocker.Unlock() BeginSelection() For Each index As Integer In OrderedSelection If CBool(selection(index)) Then SelectItem(GetRowHandleByListIndex(index)) End If Next EndSelection() ' If Not bDesAgrupando Then updateLocker.Unlock() updateLocker.Unlock() End Sub Private selection As New Hashtable() Private ReadOnly Property OrderedSelection() As IEnumerable Get Return selection.Keys.Cast(Of Integer)().OrderBy(Function(x) x) End Get End Property Protected Overrides Sub OnItemsSourceChanged(oldValue As Object, newValue As Object) MyBase.OnItemsSourceChanged(oldValue, newValue) selection.Clear() Dim itemsSource As IEnumerable = TryCast(newValue, IEnumerable) If itemsSource Is Nothing Then Return End If Dim i As Integer = 0 For Each item As Object In itemsSource selection(System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)) = False Next End Sub Protected Overrides Sub OnInitialized(e As EventArgs) MyBase.OnInitialized(e) Try ' If Me.SelectionMode = MultiSelectMode.MultipleRow Then AddHandler SelectionChanged, AddressOf MyGridControl_SelectionChanged ElementosSeleccionados = New ObservableCollectionCore(Of Object)() AddHandler Me.EndGrouping, AddressOf MyGridControl_EndGrouping AddHandler Me.StartGrouping, AddressOf MyGridControl_StartGrouping If Me.PropiedadesTSGC.BusquedaAcentosInsensitivo OrElse Configuracion.BusquedaAcentosInsensitivo Then AddHandler Me.CustomRowFilter, AddressOf MyGridControl_CustomRowFilter ConSeleccion = True '''' NumeroColumnasAgrupadas = ObtieneNumeroColumnasAgrupadas() ' End If If Me.View IsNot Nothing Then If Me.View.GetType Is GetType(TableView) Then DirectCast(Me.View, TableView).AllowFixedColumnMenu = True '''' DirectCast(Me.View, TableView).UseLightweightTemplates = UseLightweightTemplates.None '''' DirectCast(Me.View, TableView).GroupSummaryContentStyle = DirectCast(Me.FindResource("tsGroupSummaryContentStyle"), Style) '''' DirectCast(Me.View, TableView).TotalSummaryContentStyle = DirectCast(Me.FindResource("tsTotalSummaryContentStyle"), Style) End If If Configuracion.ModoBusquedaAND Then ' Me.View.SearchPanelCriteriaOperatorType = DevExpress.Xpf.Editors.CriteriaOperatorType.And Me.View.SearchPanelParseMode = DevExpress.Xpf.Editors.SearchPanelParseMode.And End If DirectCast(Me.View, GridViewBase).SearchPanelPosition = SearchPanelPosition.OverGroupPanel End If Catch ex As Exception Debug.Write(ex.Message) End Try End Sub Private Sub MyGridControl_CustomRowFilter(sender As Object, e As RowFilterEventArgs) Dim gc As GridControl = TryCast(sender, GridControl) If gc.ItemsSource IsNot Nothing Then If gc IsNot Nothing Then Dim filterStr As String = gc.View.SearchString.NothingAVacio If filterStr <> "" Then Dim Palabras = RemoveDiacriticsCustom(filterStr.ToLowerInvariant).Split(" ") e.Visible = False e.Handled = True For Each c As GridColumn In gc.Columns Dim value As String = RemoveDiacriticsCustom(gc.GetCellDisplayText(gc.GetRowHandleByListIndex(e.ListSourceRowIndex), c).ToLowerInvariant) If c.Visible Then For Each p In Palabras If value.Contains(p) Then e.Visible = True Exit For End If Next If e.Visible Then Exit For End If Next End If End If End If End Sub Private Shared Function RemoveDiacriticsCustom(ByVal text As String) As String Return String.Concat(text.Normalize(NormalizationForm.FormD).Where(Function(ch) CharUnicodeInfo.GetUnicodeCategory(ch) <> UnicodeCategory.NonSpacingMark)).Normalize(NormalizationForm.FormC) End Function Public Sub DeshabilitaSeleccionMultiple() RemoveHandler SelectionChanged, AddressOf MyGridControl_SelectionChanged RemoveHandler Me.EndGrouping, AddressOf MyGridControl_EndGrouping RemoveHandler Me.StartGrouping, AddressOf MyGridControl_StartGrouping ConSeleccion = False End Sub Private updateLocker As New Locker() 'Public Sub SeleccionaTodo() ' Me.SelectAll() ' MyGridControl_SelectionChanged(Me, Nothing) 'End Sub Friend Sub MyGridControl_SelectionChanged(sender As Object, e As GridSelectionChangedEventArgs) Try If ConSeleccion AndAlso Not updateLocker.IsLocked Then Dim drhws = GetDataRowHandles() 'For i As Integer = 0 To VisibleRowCount - 1 For i As Integer = 0 To drhws.Count - 1 'Dim rowHandle As Integer = GetRowHandleByVisibleIndex(i) Dim rowHandle As Integer = drhws(i) selection(GetListIndexByRowHandle(rowHandle)) = View.IsRowSelected(rowHandle) Next ElementosSeleccionados.BeginUpdate() ElementosSeleccionados.Clear() For Each index As Integer In OrderedSelection If CBool(selection(index)) Then ElementosSeleccionados.Add(GetRowByListIndex(index)) End If Next ElementosSeleccionados.EndUpdate() RaiseEvent SeleccionCambiada(sender, e) End If Catch ex As Exception Debug.Write(ex.Message) End Try End Sub Protected Overrides Sub ApplyFilter(checkFilterEnabled As Boolean, Optional skipIfFilterEquals As Boolean = False) If ConSeleccion Then If DirectCast(Me.View, TableView).ShowCheckBoxSelectorColumn Then updateLocker.DoLockedAction(Sub() MyBase.ApplyFilter(checkFilterEnabled, skipIfFilterEquals) BeginSelection() For Each index As Integer In OrderedSelection If CBool(selection(index)) Then SelectItem(GetRowHandleByListIndex(index)) End If Next EndSelection() End Sub) Else MyBase.ApplyFilter(checkFilterEnabled, skipIfFilterEquals) End If Else MyBase.ApplyFilter(checkFilterEnabled, skipIfFilterEquals) End If End Sub Public Function GetDataRowHandles() As List(Of Integer) Dim rowHandles As New List(Of Integer)() For i As Integer = 0 To Me.VisibleRowCount - 1 Dim rowHandle As Integer = Me.GetRowHandleByVisibleIndex(i) If Me.IsGroupRowHandle(rowHandle) Then If Not Me.IsGroupRowExpanded(rowHandle) Then rowHandles.AddRange(GetDataRowHandlesInGroup(rowHandle)) End If Else rowHandles.Add(rowHandle) End If Next Return rowHandles End Function Public Function GetDataRowHandlesInGroup(groupRowHandle As Integer) As List(Of Integer) Dim rowHandles As New List(Of Integer)() For i As Integer = 0 To Me.GetChildRowCount(groupRowHandle) - 1 Dim rowHandle As Integer = Me.GetChildRowHandle(groupRowHandle, i) If Me.IsGroupRowHandle(rowHandle) Then rowHandles.AddRange(GetDataRowHandlesInGroup(rowHandle)) Else rowHandles.Add(rowHandle) End If Next Return rowHandles End Function Public Sub New(dcoe As IDataControlOriginationElement) MyBase.New(dcoe) ' MyBase.New() End Sub 'Protected Overrides Sub OnPreviewKeyDown(e As KeyEventArgs) ' Try ' If e.Key = Key.Space AndAlso DirectCast(Me.View, TableView).ShowCheckBoxSelectorColumn Then ' e.Handled = True ' DirectCast(Me.View, TableView).SearchString &= " " ' Debug.WriteLine("ESPACIO") ' ' MyBase.OnPreviewKeyDown(e) ' Else ' MyBase.OnPreviewKeyDown(e) ' End If ' Catch ex As Exception ' MyBase.OnPreviewKeyDown(e) ' End Try 'End Sub ' Private Cargado As Boolean = False Private ConSeleccion As Boolean = False 'Private Sub tsGridControl_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded ' If Not ConSeleccion AndAlso DirectCast(Me.View, TableView).ShowCheckBoxSelectorColumn AndAlso Me.SelectionMode = MultiSelectMode.MultipleRow Then ' AddHandler SelectionChanged, AddressOf MyGridControl_SelectionChanged ' ElementosSeleccionados = New ObservableCollectionCore(Of Object)() ' AddHandler Me.EndGrouping, AddressOf MyGridControl_EndGrouping ' AddHandler Me.StartGrouping, AddressOf MyGridControl_StartGrouping ' NumeroColumnasAgrupadas = ObtieneNumeroColumnasAgrupadas() ' ConSeleccion = True ' End If 'End Sub Public Function GetColumnType(ByVal column As GridColumn) As Type Dim columnInfo As DataColumnInfo = DataProviderBase.Columns(column.FieldName) If columnInfo Is Nothing Then Return Nothing Return columnInfo.Type End Function Public Shared Sub EstableceFilterPopupModePredeterminados(gr As tsGridControl) If Not gr.PopupFilterModeInicializado AndAlso gr.ItemsSource IsNot Nothing Then gr.PopupFilterModeInicializado = True For Each cl In gr.Columns Dim tipo = gr.GetColumnType(cl) Select Case tipo Case GetType(String), GetType(Integer), GetType(Integer?), GetType(Double), GetType(Double?) cl.FilterPopupMode = FilterPopupMode.CheckedList Case GetType(Date), GetType(DateTime), GetType(Date?), GetType(DateTime?) cl.FilterPopupMode = FilterPopupMode.Excel End Select Next End If End Sub Private Sub tsGridControl_ItemsSourceChanged(sender As Object, e As ItemsSourceChangedEventArgs) Handles Me.ItemsSourceChanged EstableceFilterPopupModePredeterminados(sender) ElementosSeleccionados = New ObservableCollectionCore(Of Object)() End Sub Private Property _SeleccionMultiple As Boolean Public Property SeleccionMultiple As Boolean Get Return _SeleccionMultiple End Get Set(value As Boolean) _SeleccionMultiple = value If value Then Me.SelectionMode = MultiSelectMode.MultipleRow Else Me.SelectionMode = MultiSelectMode.None End If End Set End Property Private Sub tsGridControl_PreviewKeyDown(sender As Object, e As KeyEventArgs) Handles Me.PreviewKeyDown Select Case e.Key Case Key.Add If _SeleccionMultiple Then Me.SelectAll() e.Handled = True End If Case Key.Subtract If _SeleccionMultiple Then Me.UnselectAll() e.Handled = True End If Case Key.N If e.KeyboardDevice.IsKeyDown(Key.LeftCtrl) Then Me.View.MoveNextRow() Me.CurrentColumn = Me.Columns(0) End If End Select End Sub End Class Public Class tsGridColumn Inherits DevExpress.Xpf.Grid.GridColumn Public Property SoloLectura As Boolean Public Property Imprimible As Boolean = True Property ValorMinimo As Nullable(Of Double) Property ValorMaximo As Nullable(Of Double) Public Property MayusculasMinusculas As CharacterCasing? = Nothing Public Property CapturarEnter As Boolean Private Sub tsGridColumn_Validate(sender As Object, e As DevExpress.Xpf.Grid.GridCellValidationEventArgs) Handles Me.Validate If Not ValorMinimo Is Nothing Then If ValorMinimo > e.Value Then e.IsValid = False e.SetError("Valor Mínimo=" & ValorMinimo.ToString) End If End If If Not ValorMaximo Is Nothing Then If ValorMaximo < e.Value Then e.IsValid = False e.SetError("Valor Máximo=" & ValorMaximo.ToString) End If End If End Sub 'Private Function IsColumnCheckBoxSelectorColumn(column As ColumnBase) As Boolean ' Return column = DirectCast(Me.View, TableView).VisibleColumns.First() 'End Function End Class