Imports System.Text
Imports C1.WPF.DataGrid
Imports System.Xml.Serialization
Imports System.IO
Imports System.Windows.Threading

Namespace DataGrid_SaveState
	''' <summary>
	''' Interaction logic for MainWindow.xaml
	''' </summary>
	Partial Public Class MainWindow
		Inherits Window
		Private doneLoading As Boolean
		Private _saveSettingTimer As DispatcherTimer

		Public Sub New()
			InitializeComponent()


			AddHandler c1DataGrid1.ColumnReordered, AddressOf c1DataGrid1_ColumnReordered
			AddHandler c1DataGrid1.SortChanged, AddressOf c1DataGrid1_SortChanged
			AddHandler c1DataGrid1.GroupChanged, AddressOf c1DataGrid1_GroupChanged
			AddHandler c1DataGrid1.FilterChanged, AddressOf c1DataGrid1_FilterChanged
			AddHandler c1DataGrid1.FrozenColumnCountChanged, AddressOf c1DataGrid1_FrozenColumnCountChanged
			AddHandler c1DataGrid1.AutoGeneratedColumns, AddressOf c1DataGrid1_AutoGeneratedColumns

			c1DataGrid1.ItemsSource = Person.Generate(5000)
			doneLoading = True
			_saveSettingTimer = New DispatcherTimer()
			_saveSettingTimer.Interval = TimeSpan.FromSeconds(0.5)
			AddHandler _saveSettingTimer.Tick, AddressOf SaveDataGridSettings
		End Sub

		Private Sub c1DataGrid1_AutoGeneratedColumns(ByVal sender As Object, ByVal e As EventArgs)
			'c1DataGrid1.Columns["ImageUrl"].DisplayIndex = 0;
			If HasDataGridSettings() Then
				Dim dataGridSettings = GetDataGridSettings()
				c1DataGrid1.FrozenColumnCount = dataGridSettings.FrozenColumnsCount
				Dim sortDict = New Dictionary(Of C1.WPF.DataGrid.DataGridColumn, UserColumnSettings.SortGroupState)()
				Dim groupDict = New Dictionary(Of C1.WPF.DataGrid.DataGridColumn, UserColumnSettings.SortGroupState)()
				Dim filterList = New List(Of KeyValuePair(Of C1.WPF.DataGrid.DataGridColumn, DataGridFilterState))()
				For Each columnSetting In dataGridSettings.ColumnSettings
					Dim column = c1DataGrid1.Columns(columnSetting.ColumnName)
					If column IsNot Nothing Then
						column.DisplayIndex = columnSetting.DisplayIndex
						sortDict(column) = columnSetting.Sort
						groupDict(column) = columnSetting.Group
						filterList.Add(New KeyValuePair(Of C1.WPF.DataGrid.DataGridColumn, C1.WPF.DataGrid.DataGridFilterState)(column, columnSetting.Filter))
						If columnSetting.Width > 0 Then
							column.Width = New C1.WPF.DataGrid.DataGridLength(columnSetting.Width)
						End If
					End If
				Next columnSetting
				If filterList.Count > 0 Then
					c1DataGrid1.FilterBy(filterList.ToArray())
				End If
				If sortDict.Count > 0 Then
					Dim sortparam = sortDict.OrderBy(Function(pair) pair.Value.Index).Select(Function(pair) New KeyValuePair(Of C1.WPF.DataGrid.DataGridColumn, DataGridSortDirection)(pair.Key, pair.Value.Direction)).ToArray()
					c1DataGrid1.SortBy(sortDict.OrderBy(Function(pair) pair.Value.Index).Select(Function(pair) New KeyValuePair(Of C1.WPF.DataGrid.DataGridColumn, DataGridSortDirection)(pair.Key, pair.Value.Direction)).ToArray())
				End If
				If groupDict.Count > 0 Then
					Dim groupparam = groupDict.OrderBy(Function(pair) pair.Value.Index).Select(Function(pair) New KeyValuePair(Of C1.WPF.DataGrid.DataGridColumn, DataGridSortDirection)(pair.Key, pair.Value.Direction)).ToArray()
					c1DataGrid1.GroupBy(groupDict.OrderBy(Function(pair) pair.Value.Index).Select(Function(pair) New KeyValuePair(Of C1.WPF.DataGrid.DataGridColumn, DataGridSortDirection)(pair.Key, pair.Value.Direction)).ToArray())
				End If
			Else
				SaveDataGridSettingsAsync()
			End If
			For Each column In c1DataGrid1.Columns
				AddHandler column.WidthChanged, AddressOf column_WidthChanged
			Next column
		End Sub

		Private Sub column_WidthChanged(ByVal sender As Object, ByVal e As C1.WPF.PropertyChangedEventArgs(Of C1.WPF.DataGrid.DataGridLength))
			SaveDataGridSettingsAsync()
		End Sub

		Private Sub c1DataGrid1_FrozenColumnCountChanged(ByVal sender As Object, ByVal e As C1.WPF.PropertyChangedEventArgs(Of Integer))
			SaveDataGridSettingsAsync()
		End Sub

		Private Sub c1DataGrid1_FilterChanged(ByVal sender As Object, ByVal e As DataGridFilterChangedEventArgs)
			SaveDataGridSettingsAsync()
		End Sub

		Private Sub c1DataGrid1_GroupChanged(ByVal sender As Object, ByVal e As DataGridGroupChangedEventArgs)
			SaveDataGridSettingsAsync()
		End Sub

		Private Sub c1DataGrid1_SortChanged(ByVal sender As Object, ByVal e As DataGridSortChangedEventArgs)
			SaveDataGridSettingsAsync()
		End Sub

		Private Sub c1DataGrid1_ColumnReordered(ByVal sender As Object, ByVal e As C1.WPF.DataGrid.DataGridColumnEventArgs)
			SaveDataGridSettingsAsync()
		End Sub

		Private Function HasDataGridSettings() As Boolean
			Return Not String.IsNullOrEmpty(My.Settings.Default.DataGridSettings)
		End Function


		Private Sub SaveDataGridSettingsAsync()
			If Not doneLoading Then
				Return
			End If
			_saveSettingTimer.Start()
		End Sub

		Private Sub SaveDataGridSettings(ByVal sender As Object, ByVal e As EventArgs)
			_saveSettingTimer.Stop()
			Dim settings As New DataGridSettings()

			' get state from grid
			settings.FrozenColumnsCount = c1DataGrid1.FrozenColumnCount
			For Each column In c1DataGrid1.Columns
				Dim columnSetting As New UserColumnSettings()
				columnSetting.ColumnName = column.Name
				columnSetting.DisplayIndex = column.DisplayIndex
				columnSetting.Sort = New UserColumnSettings.SortGroupState() With {.Direction = column.SortState.Direction, .Index = column.SortState.Index}
				columnSetting.Group = New UserColumnSettings.SortGroupState() With {.Direction = column.GroupState.Direction, .Index = column.GroupState.Index}
				columnSetting.Filter = column.FilterState
				columnSetting.Width = If(column.Width.IsAbsolute, column.Width.Value, -1)

				settings.ColumnSettings.Add(columnSetting)
			Next column

			' serialize DataGridSettings class to XML
			Dim ser As XmlSerializer = CreateSerializer()
			Dim sw As New StringWriter()
			ser.Serialize(sw, settings)

			' save to user settings
			My.Settings.Default.DataGridSettings = sw.ToString()

			' save all settings
			My.Settings.Default.Save()
		End Sub

		Private Function GetDataGridSettings() As DataGridSettings
			Dim sr As New StringReader(My.Settings.Default.DataGridSettings)
			Try
				Dim ser As XmlSerializer = CreateSerializer()
				Return CType(ser.Deserialize(sr), DataGridSettings)
			Catch

			End Try

			Return New DataGridSettings()
		End Function

		Private Shared Function CreateSerializer() As XmlSerializer
			' DataGridComboBoxFilter needs List<object>
			Return New XmlSerializer(GetType(DataGridSettings), { GetType(List(Of Object)) })
		End Function
	End Class

	Public Class UserColumnSettings
		Public Class SortGroupState
			Public Property Direction() As DataGridSortDirection
			Public Property Index() As Integer
		End Class
		Public Property ColumnName() As String
		Public Property DisplayIndex() As Integer
		Public Property Sort() As SortGroupState
		Public Property Group() As SortGroupState
		Public Property Filter() As DataGridFilterState
		Public Property Width() As Double
	End Class

	Public Class DataGridSettings
		Public Sub New()
			ColumnSettings = New List(Of UserColumnSettings)()
		End Sub
		Public Property ColumnSettings() As List(Of UserColumnSettings)
		Public Property FrozenColumnsCount() As Integer
	End Class
End Namespace
