using System; using System.ComponentModel; using System.Data; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; using System.Diagnostics; using Microsoft.Win32; using System.Xml.Linq; using System.Collections.Generic; using NPOI.SS.UserModel; using System.IO; using NPOI.XSSF.UserModel; using NPOI.HSSF.UserModel; using System.Collections.ObjectModel; using MetroGauges.General; using MetroGauges.Model; using MetroGauges.ViewModel; using System.Linq; namespace MetroGauges { /// /// Line_equipment_gauge.xaml 的交互逻辑 /// public partial class WpfLiEqui { DgViewModel vm; bool IsCal=false; public WpfLiEqui() { vm = new DgViewModel(); InitializeComponent(); } /// /// 获取单元格类型 /// /// /// private static object GetValueType(ICell cell) { if (cell == null) return null; switch (cell.CellType) { case CellType.Blank: //BLANK: return null; case CellType.Boolean: //BOOLEAN: return cell.BooleanCellValue; case CellType.Numeric: //NUMERIC: return cell.NumericCellValue; case CellType.String: //STRING: return cell.StringCellValue; case CellType.Error: //ERROR: return cell.ErrorCellValue; case CellType.Formula: //FORMULA: default: return "=" + cell.CellFormula; } } #region 工具栏 private void BtnCAD_Click(object sender, RoutedEventArgs e) { if (!IsCal) { MessageBox.Show("请先计算限界", "提示"); return; } ObservableCollection othCoordPoints = new ObservableCollection(); ObservableCollection pgCoordPoints = new ObservableCollection(); ObservableCollection dm = vm.Items; for (int i = 0; i < dm.Count; i++) { if (dm[i].Position2 == PositionII.Pantograph) { pgCoordPoints.Add(dm[i]); } else { othCoordPoints.Add(dm[i]); } } if (pgCoordPoints.Count == 0 || othCoordPoints.Count == 0) { ParaSetBar.MessageQueue.Enqueue("数据不全"); return; } //去除autocad绑定 CadHelper cadHelper = new CadHelper(); List groups = new List(); foreach (var item in pgCoordPoints) { var lastchar = item.Name.Substring(item.Name.Length - 1, 1); if (!groups.Contains(lastchar)) { groups.Add(lastchar); } } List> listli = new List>(); for (int i = 0; i < groups.Count; i++) { List list = new List(); for (int j = 0; j < pgCoordPoints.Count; j++) { if (pgCoordPoints[j].Name.EndsWith(groups[i])) { list.Add(pgCoordPoints[j]); } } var ordered = list.OrderBy(k => k.Name).ToList(); listli.Add(new ObservableCollection(ordered)); } foreach (var item in listli) { CadDrawer(cadHelper, true, item); CadDrawer(cadHelper, false, item); } cadHelper.AddLayer("直线设备限界", CadHelper.RED); CadDrawer(cadHelper, true, othCoordPoints); CadDrawer(cadHelper, false, othCoordPoints); cadHelper.ZoomAll(); } //去除autocad绑定 private void CadDrawer(CadHelper cadHelper, bool isRight, ObservableCollection models) { double[] PtSt = new double[2]; double[] PtEn = new double[2]; string Corder = models[0].Name; PtSt[0] = -models[0].Xr; PtSt[1] = models[0].Yr; if (isRight) { PtSt[0] = models[0].Xr; } for (int i = 1; i < models.Count; i++) { PtEn[0] = -models[i].Xr; PtEn[1] = models[i].Yr; if (isRight) { PtEn[0] = models[i].Xr; cadHelper.DrawText(Corder + "(" + PtSt[0] + "," + PtSt[1] + ")", PtSt); } cadHelper.DrawLine(PtSt, PtEn); PtSt[0] = PtEn[0]; PtSt[1] = PtEn[1]; Corder = models[i].Name; if (models.Count - 1 == i && isRight) { cadHelper.DrawText(Corder + "(" + PtSt[0] + "," + PtSt[1] + ")", PtEn); } } } private void BtnExcel_Click(object sender, RoutedEventArgs e) { if (!IsCal) { MessageBox.Show("请先计算限界","提示" ); return; } if (vm.Items != null) { SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "Excel 工作簿(*.xlsx)|*.xlsx|Excel 97-2003 工作簿(*.xls)|*.xls"; sfd.FileName = "直线段设备限界"; //默认保存格式 sfd.DefaultExt = "xml"; //自动添加扩展名 sfd.AddExtension = true; if (sfd.ShowDialog() == true) { IWorkbook workbook; string fileExt = System.IO.Path.GetExtension(sfd.FileName).ToLower(); if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(); } else { workbook = null; } if (workbook == null) { return; } //ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("车辆限界计算表") : workbook.CreateSheet(dt.TableName); ISheet sheet = workbook.CreateSheet("直线段设备限界数据表"); List CommentList = new List(); CommentList.Add("控制点所在位置"); CommentList.Add("点号"); CommentList.Add("横坐标"); CommentList.Add("纵坐标"); CommentList.Add("直线设备限界横坐标"); CommentList.Add("直线设备限界纵坐标"); CommentList.Add("总横向偏移量"); CommentList.Add("总竖向偏移量"); ICellStyle style = workbook.CreateCellStyle(); style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center; //表头 IRow r0 = sheet.CreateRow(0); IDrawing draw = sheet.CreateDrawingPatriarch(); ICreationHelper help = workbook.GetCreationHelper(); for (int i = 0; i < dataGrid.Columns.Count; i++) { IComment com = draw.CreateCellComment(draw.CreateAnchor(0, 0, 0, 0, 0, 3, 3, 4)); //IRichTextString str; com.String = help.CreateRichTextString(CommentList[i]); ICell cell = r0.CreateCell(i); cell.SetCellValue(dataGrid.Columns[i].Header.ToString()); cell.CellComment = com; cell.CellStyle = style; } for (int i = 0; i < vm.Items.Count; i++) { dataGrid.ScrollIntoView(dataGrid.Items[i]); dataGrid.UpdateLayout(); IRow row = sheet.CreateRow(i + 1); for (int j = 0; j < dataGrid.Columns.Count; j++) { ICell cell = row.CreateCell(j); FrameworkElement cellvalue = dataGrid.Columns[j].GetCellContent(dataGrid.Items[i]); if (j == 0) { cell.SetCellValue((cellvalue as ComboBox).Text); } else { cell.SetCellValue((cellvalue as TextBlock).Text); } cell.CellStyle = style; sheet.AutoSizeColumn(j); } } dataGrid.ScrollIntoView(dataGrid.Items[0]); dataGrid.UpdateLayout(); //转为字节数组 MemoryStream stream = new MemoryStream(); workbook.Write(stream); var buf = stream.ToArray(); //保存为Excel文件 using (FileStream fs = new FileStream(sfd.FileName, FileMode.Create, FileAccess.Write)) { fs.Write(buf, 0, buf.Length); fs.Flush(); } } } } private void BtnOpen_Click(object sender, RoutedEventArgs e) { OpenFileDialog ofd = new OpenFileDialog { Filter = "XML文件(*.xml)|*.xml", Title = "打开文件", RestoreDirectory = true }; if (ofd.ShowDialog() == true && ofd.CheckFileExists == true) { //完整路径 string file = ofd.FileName; vm.Items.Clear(); XDocument document = XDocument.Load(file); XElement root = document.Root; if (root.FirstAttribute.Value == "车辆限界点") { //获取根元素下的所有子元素 IEnumerable enumerable = root.Elements(); foreach (var xe in enumerable) { LiEquiModel data = new LiEquiModel(); data.StrPosition = xe.Name.LocalName; data.Name = (string)xe.Attribute("点号"); data.X = (double)xe.Attribute("X"); data.Y = (double)xe.Attribute("Y"); vm.Items.Add(data); } } } } private void BtnSave_Click(object sender, RoutedEventArgs e) { SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "文本文件(*.xml)|*.xml"; sfd.FileName = "车辆限界数据(已定义点位)"; //默认保存格式 sfd.DefaultExt = "xml"; //自动添加扩展名 sfd.AddExtension = true; if (sfd.ShowDialog() == true) { XDocument document = new XDocument(); //实例化根节点 XElement root = new XElement("控制点坐标"); root.SetAttributeValue("车型", "无"); root.SetAttributeValue("控制点类型", "车辆限界点"); //循环所有list中的DataTable for (int i = 0; i < vm.Items.Count; i++) { var dm = vm.Items[i]; XElement childXml = new XElement(dm.Position.GetDescription()); //XElement point = new XElement(dm.StrPosition); //设置点节点的属性 childXml.SetAttributeValue("点号", dm.Name); childXml.SetAttributeValue("X", dm.X); childXml.SetAttributeValue("Y", dm.Y); //将点的节点添加到上级节点中 //childXml.Add(point); //将位置的节点添加到根节点 root.Add(childXml); } root.Save(sfd.FileName); } } private void BtnSaveGauges_Click(object sender, RoutedEventArgs e) { if (!IsCal) { MessageBox.Show("请先计算限界", "提示"); return; } SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "文本文件(*.xml)|*.xml"; sfd.FileName = "直线设备限界数据"; sfd.DefaultExt = "xml"; sfd.AddExtension = true; if (sfd.ShowDialog() == true) { XDocument document = new XDocument(); XElement root = new XElement("控制点坐标"); root.SetAttributeValue("控制点类型", "直线设备限界点"); for (int i = 0; i < vm.Items.Count; i++) { var dm = vm.Items[i]; XElement childXml = new XElement(dm.Position2.GetDescription()); childXml.SetAttributeValue("点号", dm.Name); childXml.SetAttributeValue("X", dm.Xr); childXml.SetAttributeValue("Y", dm.Yr); root.Add(childXml); } root.Save(sfd.FileName); } } private void AddPoints(DataTable dt, XElement root, string child) { XElement childXml = new XElement(child); for (int i = 0; i < dt.Rows.Count; i++) { XElement point = new XElement("坐标点"); point.SetAttributeValue("点号", dt.Rows[i][0].ToString()); point.SetAttributeValue("X", dt.Rows[i][1].ToString()); point.SetAttributeValue("Y", dt.Rows[i][2].ToString()); childXml.Add(point); } root.Add(childXml); } private void Help_Click(object sender, RoutedEventArgs e) { Process.Start(".\\HelpFile.pdf"); } protected override void OnClosing(CancelEventArgs e) { base.OnClosing(e); e.Cancel = true; Hide(); } private void Btnclear_Click(object sender, RoutedEventArgs e) { vm.Items.Clear(); IsCal=false; } private void BtnPreview_Click(object sender, RoutedEventArgs e) { if (!IsCal) { MessageBox.Show("请先计算限界", "提示"); return; } WpfPreview pre = new WpfPreview(vm); pre.ShowDialog(); } private void BtnCalc_Click(object sender, RoutedEventArgs e) { IsCal = true; for (int i = 0; i < vm.Items.Count; i++) { LiEquiModel model = vm.Items[i]; switch (model.Position2) { case PositionII.Pantograph: model.ΔXr = model.ΔX_a; model.ΔYr = model.ΔY_a; break; case PositionII.TopBody: model.ΔXr = 0; model.ΔYr = model.ΔY_b; break; case PositionII.UpChassis: model.ΔXr = model.ΔX_c; model.ΔYr = 0; break; case PositionII.LowChassis: model.ΔXr = model.ΔX_d; model.ΔYr = model.ΔY_d; break; case PositionII.Bogie: model.ΔXr = model.ΔX_e; model.ΔYr = model.ΔY_e; break; case PositionII.InnerBodyHanger: model.ΔXr = model.ΔX_f; model.ΔYr = model.ΔY_f; break; case PositionII.OuterBodyHanger: model.ΔXr = model.ΔX_f; model.ΔYr = model.ΔY_g; break; case PositionII.Wheelset: model.ΔXr = 0; model.ΔYr = 0; break; case PositionII.INVAIL: break; } } dataGrid.CommitEdit(); dataGrid.Items.Refresh(); } #endregion #region 窗体 private void Window_Loaded(object sender, RoutedEventArgs e) { //dataGrid.ItemsSource = vm.Item; ΔX_a.Text = "30"; ΔY_a.Text = "30"; ΔY_b.Text = "30"; ΔX_c.Text = "30"; ΔX_d.Text = "20"; ΔY_d.Text = "-20"; ΔX_e.Text = "15"; ΔY_e.Text = "-15"; ΔX_f.Text = "25"; ΔY_f.Text = "-30"; ΔY_g.Text = "-25"; dataGrid.DataContext = vm; } private void WindowMinimize_Click(object sender, RoutedEventArgs e) { this.WindowState = WindowState.Minimized; } private void WindowClose_Click(object sender, RoutedEventArgs e) { Hide(); } private void HeaderZone_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { DragMove(); } private void BtnPalette_Click(object sender, RoutedEventArgs e) { WpfPalette colorset = new WpfPalette(); colorset.ShowDialog(); } #endregion #region 表格操作 private void BtnDeleteRow_Click(object sender, RoutedEventArgs e) { if (dataGrid.SelectedItem != null) { vm.Items.RemoveAt(dataGrid.SelectedIndex); } } private void BtnForwardRow_Click(object sender, RoutedEventArgs e) { LiEquiModel selecteditem = (LiEquiModel)dataGrid.SelectedItem; var index = dataGrid.SelectedIndex; if (index > 0) { vm.Items.RemoveAt(index); vm.Items.Insert(index - 1, selecteditem); dataGrid.SelectedIndex = index - 1; } IsCal = false; } private void BtnBackwardRow_Click(object sender, RoutedEventArgs e) { LiEquiModel selecteditem = (LiEquiModel)dataGrid.SelectedItem; var index = dataGrid.SelectedIndex; if (index < vm.Items.Count - 1 && index != -1) { vm.Items.RemoveAt(index); vm.Items.Insert(index + 1, selecteditem); dataGrid.SelectedIndex = index + 1; } IsCal = false; } private void BtnAddRowAfter_Click(object sender, RoutedEventArgs e) { if (dataGrid.SelectedItem != null) { LiEquiModel lieq = (LiEquiModel)dataGrid.SelectedItem; vm.Items.Insert(dataGrid.SelectedIndex + 1,LiEquiModel.Copy(lieq)); } IsCal = false; } private void BtnAddRowBefore_Click(object sender, RoutedEventArgs e) { if (dataGrid.SelectedItem != null) { LiEquiModel lieq = (LiEquiModel)dataGrid.SelectedItem; vm.Items.Insert(dataGrid.SelectedIndex, LiEquiModel.Copy(lieq)); } IsCal = false; } private void BtnAddRowLast_Click(object sender, RoutedEventArgs e) { vm.Items.Add(new LiEquiModel()); IsCal = false; } #endregion } }