WPFuser as promised: no warranties implied =)
Imports
Xceed.Wpf.DataGrid
Imports
System.ComponentModel
Public
Class XceedGridExtended
Inherits Xceed.Wpf.DataGrid.DataGridControl
Private Delegate Sub ScrollMouseDelegate(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
Protected WithEvents sv As System.Windows.Controls.ScrollViewer
Private verticalScrollBar As System.Windows.Controls.Primitives.ScrollBar
Private layoutUpdateNeeded As Boolean = False
Private inDesignMode As Boolean = False
Dim scrollBarDelegate As New MouseButtonEventHandler(AddressOf ScrollBarMouseUp_Handler)
Dim scrollBarMouseWheelDelegate As New MouseWheelEventHandler(AddressOf ScrollBar_MouseWheelHandler)
Dim scrollViewerDelegate As New MouseButtonEventHandler(AddressOf ScrollViewerMouseUp_Handler)
'to raise a selection changed event we tap into the dependency property world
Dim SelectedItemChangedDescriptor As DependencyPropertyDescriptor = _
DependencyPropertyDescriptor.FromProperty(DataGridControl.SelectedItemProperty,
GetType(DataGridControl))
Public Event SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs)
#Region
"Constructor"
Public Sub New()
MyBase.New()
'check if we are in design mode or runtime
inDesignMode = System.ComponentModel.DesignerProperties.GetIsInDesignMode(
Me)
If Not inDesignMode Then
'add a selectionchanged event
SelectedItemChangedDescriptor.AddValueChanged(
Me, AddressOf OnSelectionChanged)
End If
End Sub
#End
Region
#Region
"Event handlers"
Private Sub XceedGridExtended_LayoutUpdated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LayoutUpdated
'Debug.WriteLine("updating layout")
If layoutUpdateNeeded Then
UpdateColumns()
layoutUpdateNeeded =
False
End If
End Sub
Protected Overrides Sub OnItemsChanged(ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs)
'when we add stuff to the grid then we'll need to fit
MyBase.OnItemsChanged(e)
layoutUpdateNeeded =
True
End Sub
Protected Overrides Sub OnItemsSourceChanged(ByVal oldValue As System.Collections.IEnumerable, ByVal newValue As System.Collections.IEnumerable)
'update columns when the datasource is changed
MyBase.OnItemsSourceChanged(oldValue, newValue)
layoutUpdateNeeded =
True
End Sub
Private Sub XceedGridExtended_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
'update columns when loaded
UpdateColumns()
End Sub
Public Overrides Sub OnApplyTemplate()
If Not inDesignMode Then
'catch the applytemplate and find the scrollviewer in the template
MyBase.OnApplyTemplate()
sv =
Me.Template.FindName("PART_ScrollViewer", Me)
'add a catch to find the vertical scrollbar when we need it, since we cant find it here :(
sv.AddHandler(UIElement.MouseLeftButtonUpEvent, scrollViewerDelegate,
True)
sv.AddHandler(ScrollViewer.PreviewMouseWheelEvent, scrollBarMouseWheelDelegate)
End If
End Sub
Private Sub ScrollViewerMouseUp_Handler(ByVal sender As Object, ByVal args As MouseButtonEventArgs)
'find the vertical scrollbar in the template
verticalScrollBar = sv.Template.FindName(
"PART_VerticalScrollBar", sv)
'attach a handler so we can update columns on these events
verticalScrollBar.AddHandler(UIElement.PreviewMouseWheelEvent, scrollBarMouseWheelDelegate,
True)
verticalScrollBar.AddHandler(UIElement.MouseLeftButtonUpEvent, scrollBarDelegate,
True)
'go ahead and update now
UpdateColumns()
'remove handler now we dont need it
sv.RemoveHandler(MouseLeftButtonUpEvent, scrollViewerDelegate)
End Sub
Private Sub ScrollBarMouseUp_Handler(ByVal sender As Object, ByVal args As MouseButtonEventArgs)
'resize to fit on scrollbar buttons mouse up and track mouseup
UpdateColumns()
End Sub
Private Sub ScrollBar_MouseWheelHandler(ByVal sender As Object, ByVal args As MouseWheelEventArgs)
'update the column widths on scroll wheel event
UpdateColumns()
End Sub
Private Sub OnSelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs)
'if changed selection to a valid datarow then raise selectionchanged event
If Me.CurrentItem IsNot Nothing Then
RaiseEvent SelectionChanged(sender, e)
End If
End Sub
Protected Overrides Sub Finalize()
'SelectedItemChangedDescriptor.RemoveValueChanged(Me, AddressOf OnSelectionChanged)
MyBase.Finalize()
End Sub
#End
Region
#Region
"Private methods"
Private Sub UpdateColumns()
'dont want control to freak out in design mode, so dont do anything if in design mode
If Not inDesignMode Then
'find the scrollviewer
sv =
Me.Template.FindName("PART_ScrollViewer", Me)
'find the vertical scroll bar
If sv IsNot Nothing Then
verticalScrollBar = sv.Template.FindName(
"PART_VerticalScrollBar", sv)
End If
Dim verticalScrollWidth As Double
'if the vertical scroll bar is visible then compensate for its width
If verticalScrollBar IsNot Nothing Then
If verticalScrollBar.Visibility = Windows.Visibility.Visible Then
verticalScrollWidth = verticalScrollBar.Width + 3
Else
verticalScrollWidth = 3
End If
Else
verticalScrollWidth = 3
End If
Dim fittedSize As Double = 0
'get the columsn fitted width for column
For Each c As Column In Me.Columns
'get the fitted width
If Not (c.Index = Me.Columns.Count - 1) Then
If c.GetFittedWidth > 0 And c.Visible Then
c.Width = c.GetFittedWidth + 4
'add some margin
fittedSize += c.Width.Value
ElseIf c.Visible = False Then
c.Width = 0
End If
End If
Next
'have to compensate for row selector pane and the scrollbar
Dim gridExtraColumnWidths As Double 'width of row selector pane which is defined in the theme, so this is ok
gridExtraColumnWidths += verticalScrollWidth
'compensate for rowselectorpane
'TODO Compensate for groupby when groupby has been enabled
If TypeOf Me.View Is Xceed.Wpf.DataGrid.Views.TableView Then
If CType(Me.View, Xceed.Wpf.DataGrid.Views.TableView).ShowRowSelectorPane Then gridExtraColumnWidths += 20
End If
'stretch the last column to fit the rest of the width of the grids available size
If fittedSize > Me.ActualWidth Or ((fittedSize + gridExtraColumnWidths) > Me.ActualWidth) Then
'cant do negative widths -- just a 'in case' here
Else
If Me.ActualWidth > 0 Then
If Me.Columns.Count > 0 Then
Me.Columns(Me.Columns.Count - 1).Width = Me.ActualWidth - fittedSize - gridExtraColumnWidths
End If
End If
End If
End If
End Sub
#End
Region
End
Class