using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using Newtonsoft.Json;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
using System.ComponentModel;
namespace APS.Synergy.Client.Framework.Infrastructure.DataGridExtender
{
public class DataGridExtender : DataGrid
{
public DataGridExtender()
{
this.ColumnReordered += DataGridControl_ColumnReordered;
//Cannot use layoutupdated for saving as it will save before datagrid is loaded
//this.LayoutUpdated += DataGridControl_LayoutUpdated;
//this.AutoGeneratedColumns += DataGridControl_AutoGenerateColumns;
this.Loaded += DataGridControl_Loaded;
}
private void DataGridControl_Loaded(object sender, RoutedEventArgs e)
{
var lcolumnList = ReadColumnsFromDisk();
try
{
if (lcolumnList != null && lcolumnList.Count > 0)
{
foreach (var column in lcolumnList)
{
//var litem = lcolumnList.FirstOrDefault(x => x.Header == GetColumnIdentifier(column));
var litem = this.Columns.FirstOrDefault(x => GetColumnIdentifier(x).Equals(column.Header));
if (column.ColumnWidth > 0)
{
litem.Width = new DataGridLength(column.ColumnWidth, DataGridLengthUnitType.Pixel);
}
if (litem != null)
{
//find display index and put it at the end. Let datagridcolum sort do its thing and itll push up all the way to missing columndisplayindex
//Need to do it this way otherwise if the displayindex exists in another item it does weird stuff
this.Columns.FirstOrDefault(x => x.DisplayIndex == litem.DisplayIndex).DisplayIndex = this.Columns.Count - 1;
}
}
}
//Column resize event doesnt exist so need to set one
PropertyDescriptor pd = DependencyPropertyDescriptor.FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn));
//add event to each column
foreach (DataGridColumn column in this.Columns)
{
//Add a listener for this column's width
pd.AddValueChanged(column, new EventHandler(ColumnWidthPropertyChanged));
}
}
catch (Exception ex)
{
Debug.WriteLine(String.Format("DATAGRIDEXTENDER: [Loaded] Error reloading the column layout for grid {0}: {1}", (String.IsNullOrWhiteSpace(this.ControlName) ? this.ControlName : this.DataContext.ToString()), ex.GetBaseException().Message));
Debug.WriteLine(ex.ToString());
}
}
public static readonly DependencyProperty ControlNameProperty = DependencyProperty.Register("ControlName", typeof(string), typeof(DataGridExtender));
public string ControlName
{
get
{
return System.Convert.ToString(GetValue(ControlNameProperty));
}
set
{
SetValue(ControlNameProperty, value);
}
}
private void DataGridControl_Unloaded(object sender, RoutedEventArgs e)
{
SaveColumnLayout();
}
private void DataGridControl_AutoGenerateColumns(object sender, EventArgs e)
{
var lcolumnList = ReadColumnsFromDisk();
try
{
if (lcolumnList != null && lcolumnList.Count > 0)
{
foreach (var column in this.Columns)
{
var litem = lcolumnList.FirstOrDefault(x => x.Header.Replace(" ", "") == GetColumnIdentifier(column).Replace(" ", ""));
if (litem != null)
{
column.DisplayIndex = litem.DisplayIndex;
column.Width = (litem.ColumnWidth > 0) ? new DataGridLength(litem.ColumnWidth) : Double.NaN;
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine(String.Format("DATAGRIDEXTENDER: [AutoGenerateColumns] Error reloading the column layout for grid {0}: {1}", (String.IsNullOrWhiteSpace(this.ControlName) ? this.ControlName : this.DataContext.ToString()), ex.GetBaseException().Message));
Debug.WriteLine(ex.ToString());
}
}
private string GetColumnIdentifier(DataGridColumn column)
{
// If the column has am x:Name set, then use that is the
// identifer, otherwise try the header, otherwise make something up
if (column is DataGridTextColumnExtender && !String.IsNullOrWhiteSpace(((DataGridTextColumnExtender)column).ColumnName))
{
return ((DataGridTextColumnExtender)column).ColumnName;
}
if (column is DataGridTemplateColumnExtender && !String.IsNullOrWhiteSpace(((DataGridTemplateColumnExtender)column).ColumnName))
{
return ((DataGridTemplateColumnExtender)column).ColumnName;
}
if (column is DataGridCheckBoxColumnExtender && !String.IsNullOrWhiteSpace(((DataGridCheckBoxColumnExtender)column).ColumnName))
{
return ((DataGridCheckBoxColumnExtender)column).ColumnName;
}
if (column is DataGridComboBoxColumnExtender && !String.IsNullOrWhiteSpace(((DataGridComboBoxColumnExtender)column).ColumnName))
{
return ((DataGridComboBoxColumnExtender)column).ColumnName;
}
if (column is DataGridHyperlinkColumnExtender && !String.IsNullOrWhiteSpace(((DataGridHyperlinkColumnExtender)column).ColumnName))
{
return ((DataGridHyperlinkColumnExtender)column).ColumnName;
}
if (column.Header != null && !String.IsNullOrWhiteSpace(column.Header.ToString()))
{
return column.Header.ToString();
}
return "column_" + this.Columns.IndexOf(column);
// Everything has failed so we need to try and use something else
}
private void DataGridControl_ColumnReordered(object sender, DataGridColumnEventArgs e)
{
SaveColumnLayout();
}
private void DataGridControl_LayoutUpdated(object sender, EventArgs e)
{
SaveColumnLayout();
}
private void SaveColumnLayout()
{
List<ColumnItem> lColumnList = new List<ColumnItem>();
ColumnItem lColumnItem;
foreach (var column in this.Columns)
{
lColumnItem = new ColumnItem() { DisplayIndex = column.DisplayIndex, Header = GetColumnIdentifier(column), ColumnWidth = column.Width.DesiredValue };
lColumnList.Add(lColumnItem);
}
lColumnList = lColumnList.OrderBy(x => x.DisplayIndex).ToList();
WriteColumnsToDisk(lColumnList);
}
private void WriteColumnsToDisk(List<ColumnItem> columnList)
{
string file = string.Empty;
try
{
file = GetDataGridFileName();
var path = System.IO.Path.GetDirectoryName(file);
if (!System.IO.Directory.Exists(path))
System.IO.Directory.CreateDirectory(path);
var contents = Newtonsoft.Json.JsonConvert.SerializeObject(columnList);
System.IO.File.WriteAllText(GetDataGridFileName(), contents);
}
catch (Exception ex)
{
Debug.WriteLine("Failed to save datagrid columns to {0} : {1}", file, ex.GetBaseException().Message);
Debug.WriteLine(ex.ToString());
}
}
private List<ColumnItem> ReadColumnsFromDisk()
{
string file = string.Empty;
try
{
file = GetDataGridFileName();
if (System.IO.File.Exists(file))
{
var contents = System.IO.File.ReadAllText(file);
if (!string.IsNullOrWhiteSpace(contents))
{
List<ColumnItem> columnList;
columnList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ColumnItem>>(contents);
return columnList;
}
}
}
catch (Exception ex)
{
Debug.WriteLine("Failed to read datagrid columns to {0} : {1}", file, ex.GetBaseException().Message);
Debug.WriteLine(ex.ToString());
}
return null;
}
private string GetDataGridFileName()
{
if (String.IsNullOrEmpty(this.ControlName))
{
return System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "APS", "Synergy3", "Client", "Settings", this.DataContext.ToString() + "_datagrid.json");
}
return System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "APS", "Synergy3", "Client", "Settings", this.ControlName + "_datagrid.json");
}
//column width change for mouse click stuff
private bool _columnWidthChanging;
private void ColumnWidthPropertyChanged(object sender, EventArgs e)
{
// listen for when the mouse is released
_columnWidthChanging = true;
if (sender != null)
Mouse.AddPreviewMouseUpHandler(this, BaseDataGrid_MouseLeftButtonUp);
}
void BaseDataGrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_columnWidthChanging)
{
_columnWidthChanging = false;
SaveColumnLayout();
}
}
}
public class ColumnItem
{
public int DisplayIndex { get; set; }
public string Header { get; set; }
public double ColumnWidth { get; set; }
}
public class DataGridTextColumnExtender : DataGridTextColumn
{
public static readonly DependencyProperty ColumnNameProperty = DependencyProperty.Register("ColumnName", typeof(string), typeof(DataGridTextColumnExtender));
public string ColumnName
{
get
{
return System.Convert.ToString(GetValue(ColumnNameProperty));
}
set
{
SetValue(ColumnNameProperty, value);
}
}
}
public class DataGridTemplateColumnExtender : DataGridTemplateColumn
{
public static readonly DependencyProperty ColumnNameProperty = DependencyProperty.Register("ColumnName", typeof(string), typeof(DataGridTemplateColumnExtender));
public string ColumnName
{
get
{
return System.Convert.ToString(GetValue(ColumnNameProperty));
}
set
{
SetValue(ColumnNameProperty, value);
}
}
}
public class DataGridComboBoxColumnExtender : DataGridComboBoxColumn
{
public static readonly DependencyProperty ColumnNameProperty = DependencyProperty.Register("ColumnName", typeof(string), typeof(DataGridComboBoxColumnExtender));
public string ColumnName
{
get
{
return System.Convert.ToString(GetValue(ColumnNameProperty));
}
set
{
SetValue(ColumnNameProperty, value);
}
}
}
public class DataGridCheckBoxColumnExtender : DataGridCheckBoxColumn
{
public static readonly DependencyProperty ColumnNameProperty = DependencyProperty.Register("ColumnName", typeof(string), typeof(DataGridCheckBoxColumnExtender));
public string ColumnName
{
get
{
return System.Convert.ToString(GetValue(ColumnNameProperty));
}
set
{
SetValue(ColumnNameProperty, value);
}
}
}
public class DataGridHyperlinkColumnExtender : DataGridHyperlinkColumn
{
public static readonly DependencyProperty ColumnNameProperty = DependencyProperty.Register("ColumnName", typeof(string), typeof(DataGridHyperlinkColumnExtender));
public string ColumnName
{
get
{
return System.Convert.ToString(GetValue(ColumnNameProperty));
}
set
{
SetValue(ColumnNameProperty, value);
}
}
}
}