You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/UCDraw/PcgDrawR_wellPole/WellWorkDataUI/FrmGeologicalStratification.cs

655 lines
22 KiB
C#

1 month ago
// ***********************************************************************
// Assembly : Construction
// Author : zjx
// Created : 09-09-2020
//
// Last Modified By : zjx
// Last Modified On : 09-09-2020
// ***********************************************************************
// <copyright file="FrmGeologicalStratification.cs" company="jindongfang">
// Copyright (c) jindongfang. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using DevExpress.Utils;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using Fk.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WorkData;
using WorkData.Entity;
namespace WellWorkDataUI.CustomControls
{
/// <summary>
/// Class FrmGeologicalStratification.
/// Implements the <see cref="System.Windows.Forms.Form" />
/// </summary>
/// <seealso cref="System.Windows.Forms.Form" />
public partial class FrmGeologicalStratification : Form, IComparer<GeologicalStratification>
{
/// <summary>
/// Data Changed
/// </summary>
internal bool DataChanged { get; private set; } = false;
private List<GeologicalStratification> data = new List<GeologicalStratification>();
/// <summary>
/// Initializes a new instance of the <see cref="FrmGeologicalStratification"/> class.
/// </summary>
public FrmGeologicalStratification()
{
this.InitializeComponent();
this.LoadDataAsync();
}
/// <summary>
/// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
/// </summary>
/// <param name="x">x</param>
/// <param name="y">y</param>
/// <returns>compare result</returns>
public int Compare(GeologicalStratification x, GeologicalStratification y)
{
GeologicalStratification a = x;
GeologicalStratification b = y;
do
{
if (a.ParentID == b.ParentID)
{
return a.Order.CompareTo(b.Order);
}
if (a.Level == b.Level)
{
a = this.data.FirstOrDefault(o => o.ID == a.ParentID);
b = this.data.FirstOrDefault(o => o.ID == b.ParentID);
}
else if (a.Level > b.Level)
{
a = this.data.FirstOrDefault(o => o.ID == a.ParentID);
}
else if (a.Level < b.Level)
{
b = this.data.FirstOrDefault(o => o.ID == b.ParentID);
}
}
while (a != null && b != null);
return 0;
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Form.FormClosing" /> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.FormClosingEventArgs" /> that contains the event data.</param>
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (this.DataChanged && MessageBox.Show("数据已修改, 是否保存?", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
{
this.SaveData();
}
base.OnFormClosing(e);
}
/// <summary>
/// Saves the data async.
/// </summary>
/// <returns>A Task.</returns>
private void SaveData()
{
DBHelp.NewDb.Ado.ExecuteCommand("PRAGMA foreign_keys = OFF;");
DBHelp.NewDb.BulkInsert(this.data, db =>
{
db.Deleteable<GeologicalStratification>().ExecuteCommand();
});
this.DataChanged = false;
MessageBox.Show("数据保存成功!");
DataHelp.LoadGeoLayer(); //更新当前工区变量
}
private async void LoadDataAsync()
{
this.data.AddRange(await DBHelp.NewDb.Queryable<GeologicalStratification>().ToListAsync());
this.ViewData();
}
private void ViewData()
{
ModelList list = new ModelList();
List<GeologicalStratification> leafs = this.data.Where(r => !this.data.Any(o => o.ParentID == r.ID))
.OrderBy(o => o, this)
.ToList();
foreach (GeologicalStratification item in leafs)
{
dynamic model = new Model();
GeologicalStratification cur = item;
do
{
model[$"Level{cur.Level}"] = cur.Code;
model[$"Object{cur.Level}"] = cur;
list.MaxLevel = Math.Max(list.MaxLevel, cur.Level);
model.MaxLevel = Math.Max(model.MaxLevel, cur.Level);
cur = this.data.FirstOrDefault(o => o.ID == cur.ParentID);
}
while (cur != null);
list.Add(model);
}
this.gridViewMain.Columns.Clear();
for (int i = 0; i <= list.MaxLevel; i++)
{
GridColumn col = this.gridViewMain.Columns.Add();
col.Caption = $"{NumberConverter.NumToChinese(i + 1)}级分层";
col.FieldName = $"Level{i}";
col.Visible = true;
col.OptionsColumn.AllowEdit = true;
}
this.gridControl1.DataSource = list;
}
private void btnExport_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
SaveFileDialog dlg = new SaveFileDialog()
{
Filter = "分隔符文件(*.txt;*.dat;*.csv)|*.txt;*.dat;*.csv|所有文件(*.*)|*.*",
};
if (dlg.ShowDialog() == DialogResult.OK)
{
string seperator = ",";
string ext = Path.GetExtension(dlg.FileName);
if (ext.Equals(".txt", StringComparison.OrdinalIgnoreCase))
{
seperator = "\t";
}
else if (ext.Equals(".dat", StringComparison.OrdinalIgnoreCase))
{
seperator = " ";
}
if (this.gridControl1.DataSource is ModelList list)
{
StringBuilder sb = new StringBuilder();
foreach (Model item in list)
{
if (item.MaxLevel > 0)
{
dynamic model = item;
for (int i = 0; i <= item.MaxLevel; i++)
{
sb.Append(model[$"Level{i}"]);
sb.Append(seperator);
}
sb.Length -= seperator.Length;
sb.AppendLine();
}
}
File.WriteAllText(dlg.FileName, sb.ToString());
MessageBox.Show("导出数据成功!");
}
}
}
private int GetNextId()
{
return this.data.Count > 0 ? this.data.Max(o => o.ID) + 1 : 0;
}
private async Task ImportDataCore(Stream stream, Encoding encoding)
{
await DBHelp.NewDb.UseTranAsync(async db =>
{
Dictionary<string, GeologicalStratification> dict = new Dictionary<string, GeologicalStratification>();
using (StreamReader reader = new StreamReader(stream, encoding, true))
{
int nLine = 0;
while (!reader.EndOfStream)
{
string line = await reader.ReadLineAsync();
string[] arr = line.Split(Constants.StringSplit.Separator, StringSplitOptions.RemoveEmptyEntries);
if (arr.Any(o => string.IsNullOrWhiteSpace(o)))
{
this.data.Clear();
MessageBox.Show("不能为空");
return;
}
GeologicalStratification parent = null;
for (int i = 0; i < arr.Length; i++)
{
GeologicalStratification cur = null;
string key = $"{arr[i]}-{i}";
if (dict.ContainsKey(key))
{
cur = dict[key];
}
else
{
cur = new GeologicalStratification()
{
ID = this.GetNextId(),
Code = arr[i],
Level = i,
Order = nLine,
ParentID = parent?.ID ?? -1,
};
dict[key] = cur;
this.data.Add(cur);
}
parent = cur;
}
nLine++;
}
}
});
}
private async void btnPaste_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
if (Clipboard.ContainsText())
{
Encoding encoding = Encoding.Default;
using (MemoryStream stream = new MemoryStream(encoding.GetBytes(Clipboard.GetText())))
{
await this.ImportDataCore(stream, encoding);
}
this.ViewData();
this.DataChanged = true;
MessageBox.Show("粘贴数据成功!");
}
}
private async void btnImport_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog()
{
Filter = "分隔符文件(*.txt;*.dat;*.csv)|*.txt;*.dat;*.csv|所有文件(*.*)|*.*",
};
if (dlg.ShowDialog() == DialogResult.OK)
{
Encoding charset2 = EncodingType.GetType(dlg.FileName);
//using (var mmf = MemoryMappedFile.CreateFromFile(dlg.FileName, FileMode.Open, Guid.NewGuid().ToString()))
//using (var stream = mmf.CreateViewStream(0, 0))
using (MemoryStream stream = new MemoryStream(File.ReadAllBytes(dlg.FileName)))
{
await this.ImportDataCore(stream, charset2);
}
this.ViewData();
this.DataChanged = true;
MessageBox.Show("导入数据成功!");
}
}
private void btnExit_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
private void btnSave_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
this.SaveData();
this.DialogResult = DialogResult.OK;
}
private void btnDeleteAll_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
this.DataChanged = true;
this.data.Clear();
this.ViewData();
}
/// <summary>
/// 删除项
/// </summary>
private void btnDelete_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
int[] rows = this.gridViewMain.GetSelectedRows();
if (rows.Length > 0)
{
this.DataChanged = true;
foreach (int handle in rows)
{
dynamic model = this.gridViewMain.GetRow(handle);
if (model[$"Object{model.MaxLevel}"] is GeologicalStratification gs)
{
this.data.Remove(gs);
}
}
this.ViewData();
}
}
private void btnAdd_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
if (this.gridControl1.DataSource is ModelList list)
{
this.DataChanged = true;
dynamic model = this.gridViewMain.GetRow(this.gridViewMain.RowCount - 1);
dynamic newmodel = new Model();
if (model != null)
{
newmodel.MaxLevel = model.MaxLevel;
for (int i = 0; i <= model.MaxLevel - 1; i++)
{
newmodel[$"Level{i}"] = model[$"Level{i}"];
newmodel[$"Object{i}"] = model[$"Object{i}"];
}
if (model[$"Object{model.MaxLevel}"] is GeologicalStratification gs)
{
GeologicalStratification newgs = new GeologicalStratification
{
ID = this.GetNextId(),
Level = gs.Level,
Order = gs.Order + 1,
ParentID = gs.ParentID,
Code = "新建分层",
};
this.data.Add(newgs);
newmodel[$"Level{model.MaxLevel}"] = newgs.Code;
newmodel[$"Object{model.MaxLevel}"] = newgs;
}
}
else
{
GeologicalStratification newgs = new GeologicalStratification
{
ID = this.GetNextId(),
Level = 0,
Order = 0,
ParentID = -1,
Code = "新建分层",
};
this.data.Add(newgs);
newmodel[$"Level0"] = newgs.Code;
newmodel[$"Object0"] = newgs;
}
list.Add(newmodel);
}
}
private void btnInsert_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
int handle = this.gridViewMain.FocusedRowHandle;
if (this.gridControl1.DataSource is ModelList list && handle >= 0)
{
this.DataChanged = true;
dynamic model = this.gridViewMain.GetRow(handle);
dynamic newmodel = new Model() { MaxLevel = model.MaxLevel };
for (int i = 0; i <= model.MaxLevel - 1; i++)
{
newmodel[$"Level{i}"] = model[$"Level{i}"];
newmodel[$"Object{i}"] = model[$"Object{i}"];
}
if (model[$"Object{model.MaxLevel}"] is GeologicalStratification gs)
{
GeologicalStratification newgs = new GeologicalStratification
{
ID = this.GetNextId(),
Level = gs.Level,
Order = gs.Order + 1,
ParentID = gs.ParentID,
Code = "新建分层",
};
this.data.Add(newgs);
newmodel[$"Level{model.MaxLevel}"] = newgs.Code;
newmodel[$"Object{model.MaxLevel}"] = newgs;
List<GeologicalStratification> nextList = this.data.Where(o => o.ParentID == gs.ParentID && o.Order > gs.Order)
.ToList();
foreach (GeologicalStratification item in nextList)
{
item.Order += 1;
}
}
list.Insert(this.gridViewMain.FocusedRowHandle + 1, newmodel);
}
}
private void gridViewMain_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
{
//if (string.IsNullOrWhiteSpace(e.Value?.ToString()))
//{
// var oldValue = this.gridViewMain.ActiveEditor.OldEditValue;
// this.gridViewMain.SetRowCellValue(e.RowHandle, e.Column, oldValue);
// MessageBox.Show("数据不能为空!");
// return;
//}
if (e.RowHandle >= 0)
{
dynamic model = this.gridViewMain.GetRow(e.RowHandle);
int idx = e.Column.AbsoluteIndex;
if (model[$"Object{idx}"] is GeologicalStratification gs)
{
this.DataChanged = true;
gs.Code = e.Value.ToString();
}
else
{
if (model[$"Object{model.MaxLevel}"] is GeologicalStratification parent)
{
var parentId = this.data.Count == 0 ? -1 : parent.ID;
GeologicalStratification newgs = new GeologicalStratification
{
ID = this.GetNextId(),
Code = e.Value.ToString(),
Level = idx,
Order = 0,
ParentID = parentId,
};
model[$"Object{idx}"] = newgs;
model.MaxLevel = newgs.Level;
this.data.Add(newgs);
this.DataChanged = true;
}
}
}
}
private void gridViewMain_MouseDown(object sender, MouseEventArgs e)
{
GridView view = sender as GridView;
GridHitInfo hitInfo = view.CalcHitInfo(e.Location);
if (hitInfo.InRowCell)
{
hitInfo.Column.OptionsColumn.AllowEdit = true;
view.ClearSelection();
view.SelectRow(hitInfo.RowHandle);
view.FocusedRowHandle = hitInfo.RowHandle;
view.FocusedColumn = hitInfo.Column;
DXMouseEventArgs.GetMouseArgs(e).Handled = true;
if (e.Clicks == 2 && e.Button == MouseButtons.Left)
{
view.ShowEditor();
view.ActiveEditor.SelectAll();
}
}
}
private void gridViewMain_FocusedColumnChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedColumnChangedEventArgs e)
{
}
private class Model : DynamicObject
{
private readonly Dictionary<string, object> dynamicProperties = new Dictionary<string, object>();
public int MaxLevel { get; set; } = 0;
public override bool TrySetMember(SetMemberBinder binder, object value)
{
this.dynamicProperties[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (!this.dynamicProperties.TryGetValue(binder.Name, out result))
{
result = string.Empty;
}
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return this.dynamicProperties.Keys;
}
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
string key = (string)indexes[0];
this.dynamicProperties[key] = value;
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
string key = (string)indexes[0];
if (!this.dynamicProperties.TryGetValue(key, out result))
{
result = string.Empty;
}
return true;
}
}
private class ModelList : AsyncBindingList<Model>, ITypedList
{
public int MaxLevel { get; set; } = 4;
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
List<PropertyDescriptor> descriptors = new List<PropertyDescriptor>();
for (int i = 0; i <= this.MaxLevel; i++)
{
descriptors.Add(new MyDynamicPropertyDescriptor($"Level{i}", typeof(string)));
}
return new PropertyDescriptorCollection(descriptors.ToArray());
}
public string GetListName(PropertyDescriptor[] listAccessors)
{
throw new NotImplementedException();
}
private class MyDynamicPropertyDescriptor : PropertyDescriptor
{
public MyDynamicPropertyDescriptor(string name, Type type)
: base(name, null)
{
this.Type = type;
}
public Type Type { get; private set; }
public override bool IsReadOnly => false;
public override Type PropertyType => this.Type;
public override Type ComponentType => typeof(Model);
public override bool CanResetValue(object component) => throw new NotImplementedException();
public override void ResetValue(object component) => throw new NotImplementedException();
public override bool ShouldSerializeValue(object component) => throw new NotImplementedException();
public override object GetValue(object component)
{
dynamic model = component as Model;
return model[this.Name];
}
public override void SetValue(object component, object value)
{
dynamic model = component as Model;
model[this.Name] = value;
}
}
}
}
}