上传界面显示

This commit is contained in:
2025-03-16 13:11:08 +08:00
parent ca6476b87c
commit c49c45d6e4
62 changed files with 9095 additions and 1204 deletions

599
DH.UI.Model.Winform/Canvas.Designer.cs generated Normal file
View File

@ -0,0 +1,599 @@
namespace DH.UI.Model.Winform
{
partial class Canvas
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Canvas));
this.ctmsElements = new System.Windows.Forms.ContextMenuStrip(this.components);
this.tsmiResort = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiInitialState = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiClearStandardValue = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiClearActualValue = new System.Windows.Forms.ToolStripMenuItem();
this.ctmsKeepElements = new System.Windows.Forms.ContextMenuStrip(this.components);
this.tsmiUnselectElements = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiKeepSelected = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiKeepUnselected = new System.Windows.Forms.ToolStripMenuItem();
this.BottomToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.TopToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.RightToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.LeftToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.ContentPanel = new System.Windows.Forms.ToolStripContentPanel();
this.scMain = new System.Windows.Forms.SplitContainer();
this.tsROIs = new System.Windows.Forms.ToolStrip();
this.tsTool = new System.Windows.Forms.ToolStrip();
this.tsBtnLoadImage = new System.Windows.Forms.ToolStripButton();
this.tsBtnSaveImage = new System.Windows.Forms.ToolStripButton();
this.tsBtnSaveImageWithElements = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.tsBtnMapSize = new System.Windows.Forms.ToolStripButton();
this.tsBtnScreenSize = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.tsBtnModeNormal = new System.Windows.Forms.ToolStripButton();
this.tsBtnModeSelection = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.chkShowChecked = new System.Windows.Forms.CheckBox();
this.dgElements = new System.Windows.Forms.DataGridView();
this.colEnableState = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.colId = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.colIndex = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.propGridElement = new System.Windows.Forms.PropertyGrid();
this.miniToolStrip = new System.Windows.Forms.ToolStrip();
this.stsStatus = new System.Windows.Forms.StatusStrip();
this.tsslLocation = new System.Windows.Forms.ToolStripStatusLabel();
this.tsslMouseState = new System.Windows.Forms.ToolStripStatusLabel();
this.dataGridViewCheckBoxColumn1 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.ctmsElements.SuspendLayout();
this.ctmsKeepElements.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.scMain)).BeginInit();
this.scMain.Panel1.SuspendLayout();
this.scMain.Panel2.SuspendLayout();
this.scMain.SuspendLayout();
this.tsTool.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dgElements)).BeginInit();
this.stsStatus.SuspendLayout();
this.SuspendLayout();
//
// ctmsElements
//
this.ctmsElements.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsmiResort,
this.tsmiInitialState,
this.tsmiClearStandardValue,
this.tsmiClearActualValue});
this.ctmsElements.Name = "ctmsElements";
this.ctmsElements.Size = new System.Drawing.Size(137, 92);
//
// tsmiResort
//
this.tsmiResort.Name = "tsmiResort";
this.tsmiResort.Size = new System.Drawing.Size(136, 22);
this.tsmiResort.Text = "重新排序";
this.tsmiResort.Click += new System.EventHandler(this.tsmiResort_Click);
//
// tsmiInitialState
//
this.tsmiInitialState.Name = "tsmiInitialState";
this.tsmiInitialState.Size = new System.Drawing.Size(136, 22);
this.tsmiInitialState.Text = "初始化";
this.tsmiInitialState.Click += new System.EventHandler(this.tsmiInitialState_Click);
//
// tsmiClearStandardValue
//
this.tsmiClearStandardValue.Name = "tsmiClearStandardValue";
this.tsmiClearStandardValue.Size = new System.Drawing.Size(136, 22);
this.tsmiClearStandardValue.Text = "清空标准值";
this.tsmiClearStandardValue.Click += new System.EventHandler(this.tsmiClearStandardValue_Click);
//
// tsmiClearActualValue
//
this.tsmiClearActualValue.Name = "tsmiClearActualValue";
this.tsmiClearActualValue.Size = new System.Drawing.Size(136, 22);
this.tsmiClearActualValue.Text = "清空测量值";
this.tsmiClearActualValue.Click += new System.EventHandler(this.tsmiClearActualValue_Click);
//
// ctmsKeepElements
//
this.ctmsKeepElements.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsmiUnselectElements,
this.tsmiKeepSelected,
this.tsmiKeepUnselected});
this.ctmsKeepElements.Name = "ctmsKeepElements";
this.ctmsKeepElements.Size = new System.Drawing.Size(173, 70);
//
// tsmiUnselectElements
//
this.tsmiUnselectElements.Name = "tsmiUnselectElements";
this.tsmiUnselectElements.Size = new System.Drawing.Size(172, 22);
this.tsmiUnselectElements.Text = "取消全部基元选择";
this.tsmiUnselectElements.Click += new System.EventHandler(this.tsmiUnselectElements_Click);
//
// tsmiKeepSelected
//
this.tsmiKeepSelected.Name = "tsmiKeepSelected";
this.tsmiKeepSelected.Size = new System.Drawing.Size(172, 22);
this.tsmiKeepSelected.Text = "保留选中的基元";
this.tsmiKeepSelected.Click += new System.EventHandler(this.tsmiKeepSelected_Click);
//
// tsmiKeepUnselected
//
this.tsmiKeepUnselected.Name = "tsmiKeepUnselected";
this.tsmiKeepUnselected.Size = new System.Drawing.Size(172, 22);
this.tsmiKeepUnselected.Text = "保留未选中的基元";
this.tsmiKeepUnselected.Click += new System.EventHandler(this.tsmiKeepUnselected_Click);
//
// BottomToolStripPanel
//
this.BottomToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.BottomToolStripPanel.Name = "BottomToolStripPanel";
this.BottomToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.BottomToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.BottomToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// TopToolStripPanel
//
this.TopToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.TopToolStripPanel.Name = "TopToolStripPanel";
this.TopToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.TopToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.TopToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// RightToolStripPanel
//
this.RightToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.RightToolStripPanel.Name = "RightToolStripPanel";
this.RightToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.RightToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.RightToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// LeftToolStripPanel
//
this.LeftToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.LeftToolStripPanel.Name = "LeftToolStripPanel";
this.LeftToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.LeftToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.LeftToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// ContentPanel
//
this.ContentPanel.Size = new System.Drawing.Size(610, 417);
//
// scMain
//
this.scMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.scMain.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
this.scMain.Location = new System.Drawing.Point(0, 0);
this.scMain.Name = "scMain";
//
// scMain.Panel1
//
this.scMain.Panel1.Controls.Add(this.tsROIs);
this.scMain.Panel1.Controls.Add(this.tsTool);
//
// scMain.Panel2
//
this.scMain.Panel2.Controls.Add(this.splitContainer1);
this.scMain.Size = new System.Drawing.Size(635, 467);
this.scMain.SplitterDistance = 399;
this.scMain.TabIndex = 4;
//
// tsROIs
//
this.tsROIs.Location = new System.Drawing.Point(29, 0);
this.tsROIs.Name = "tsROIs";
this.tsROIs.Size = new System.Drawing.Size(370, 25);
this.tsROIs.TabIndex = 2;
this.tsROIs.Text = "toolStrip1";
this.tsROIs.Visible = false;
//
// tsTool
//
this.tsTool.Dock = System.Windows.Forms.DockStyle.Left;
this.tsTool.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.tsTool.ImageScalingSize = new System.Drawing.Size(24, 24);
this.tsTool.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsBtnLoadImage,
this.tsBtnSaveImage,
this.tsBtnSaveImageWithElements,
this.toolStripSeparator4,
this.tsBtnMapSize,
this.tsBtnScreenSize,
this.toolStripSeparator1,
this.tsBtnModeNormal,
this.tsBtnModeSelection,
this.toolStripSeparator2});
this.tsTool.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
this.tsTool.Location = new System.Drawing.Point(0, 0);
this.tsTool.Margin = new System.Windows.Forms.Padding(10, 0, 0, 0);
this.tsTool.Name = "tsTool";
this.tsTool.Size = new System.Drawing.Size(29, 467);
this.tsTool.TabIndex = 1;
this.tsTool.Text = "toolStrip1";
//
// tsBtnLoadImage
//
this.tsBtnLoadImage.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnLoadImage.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnLoadImage.Image")));
this.tsBtnLoadImage.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnLoadImage.Name = "tsBtnLoadImage";
this.tsBtnLoadImage.Size = new System.Drawing.Size(26, 28);
this.tsBtnLoadImage.Text = "LoadImage";
this.tsBtnLoadImage.ToolTipText = "Load Image";
this.tsBtnLoadImage.Click += new System.EventHandler(this.tsBtnLoadImage_Click);
//
// tsBtnSaveImage
//
this.tsBtnSaveImage.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnSaveImage.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnSaveImage.Image")));
this.tsBtnSaveImage.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnSaveImage.Name = "tsBtnSaveImage";
this.tsBtnSaveImage.Size = new System.Drawing.Size(26, 28);
this.tsBtnSaveImage.Text = "SaveImage";
this.tsBtnSaveImage.Click += new System.EventHandler(this.tsBtnSaveImage_Click);
//
// tsBtnSaveImageWithElements
//
this.tsBtnSaveImageWithElements.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnSaveImageWithElements.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnSaveImageWithElements.Image")));
this.tsBtnSaveImageWithElements.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnSaveImageWithElements.Name = "tsBtnSaveImageWithElements";
this.tsBtnSaveImageWithElements.Size = new System.Drawing.Size(26, 28);
this.tsBtnSaveImageWithElements.Text = "SaveImageWithElements";
this.tsBtnSaveImageWithElements.Click += new System.EventHandler(this.tsBtnSaveImageWithElements_Click);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(26, 6);
//
// tsBtnMapSize
//
this.tsBtnMapSize.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnMapSize.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnMapSize.Image")));
this.tsBtnMapSize.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnMapSize.Name = "tsBtnMapSize";
this.tsBtnMapSize.Size = new System.Drawing.Size(26, 28);
this.tsBtnMapSize.Text = "Original";
this.tsBtnMapSize.ToolTipText = "Map Size";
this.tsBtnMapSize.Click += new System.EventHandler(this.tsBtnMapSize_Click);
//
// tsBtnScreenSize
//
this.tsBtnScreenSize.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnScreenSize.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnScreenSize.Image")));
this.tsBtnScreenSize.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnScreenSize.Name = "tsBtnScreenSize";
this.tsBtnScreenSize.Size = new System.Drawing.Size(26, 28);
this.tsBtnScreenSize.Text = "toolStripButton2";
this.tsBtnScreenSize.ToolTipText = "Screen Size";
this.tsBtnScreenSize.Click += new System.EventHandler(this.tsBtnScreenSize_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(26, 6);
//
// tsBtnModeNormal
//
this.tsBtnModeNormal.CheckOnClick = true;
this.tsBtnModeNormal.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnModeNormal.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnModeNormal.Image")));
this.tsBtnModeNormal.ImageTransparentColor = System.Drawing.SystemColors.Control;
this.tsBtnModeNormal.Name = "tsBtnModeNormal";
this.tsBtnModeNormal.Size = new System.Drawing.Size(26, 28);
this.tsBtnModeNormal.Text = "Normal Mode";
this.tsBtnModeNormal.ToolTipText = "Normal Mode";
this.tsBtnModeNormal.CheckedChanged += new System.EventHandler(this.tsBtnModeNormal_CheckedChanged);
//
// tsBtnModeSelection
//
this.tsBtnModeSelection.CheckOnClick = true;
this.tsBtnModeSelection.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnModeSelection.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnModeSelection.Image")));
this.tsBtnModeSelection.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnModeSelection.Name = "tsBtnModeSelection";
this.tsBtnModeSelection.Size = new System.Drawing.Size(26, 28);
this.tsBtnModeSelection.Text = "Selection Mode";
this.tsBtnModeSelection.CheckedChanged += new System.EventHandler(this.tsBtnModeNormal_CheckedChanged);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(26, 6);
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.chkShowChecked);
this.splitContainer1.Panel1.Controls.Add(this.dgElements);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.propGridElement);
this.splitContainer1.Size = new System.Drawing.Size(232, 467);
this.splitContainer1.SplitterDistance = 215;
this.splitContainer1.TabIndex = 2;
//
// chkShowChecked
//
this.chkShowChecked.AutoSize = true;
this.chkShowChecked.Location = new System.Drawing.Point(14, 8);
this.chkShowChecked.Name = "chkShowChecked";
this.chkShowChecked.Size = new System.Drawing.Size(110, 17);
this.chkShowChecked.TabIndex = 1;
this.chkShowChecked.Text = "仅显示选中项目";
this.chkShowChecked.UseVisualStyleBackColor = true;
this.chkShowChecked.CheckedChanged += new System.EventHandler(this.chkShowChecked_CheckedChanged);
//
// dgElements
//
this.dgElements.AllowUserToAddRows = false;
this.dgElements.AllowUserToDeleteRows = false;
this.dgElements.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dgElements.BackgroundColor = System.Drawing.SystemColors.GradientInactiveCaption;
this.dgElements.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgElements.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.colEnableState,
this.colId,
this.colIndex,
this.colName});
this.dgElements.Location = new System.Drawing.Point(0, 30);
this.dgElements.MultiSelect = false;
this.dgElements.Name = "dgElements";
this.dgElements.RowTemplate.Height = 23;
this.dgElements.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.dgElements.Size = new System.Drawing.Size(232, 185);
this.dgElements.TabIndex = 0;
this.dgElements.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgElements_CellMouseDoubleClick);
this.dgElements.SelectionChanged += new System.EventHandler(this.dgElements_SelectionChanged);
//
// colEnableState
//
this.colEnableState.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.colEnableState.DataPropertyName = "IsEnabled";
this.colEnableState.FillWeight = 41.95804F;
this.colEnableState.HeaderText = "";
this.colEnableState.MinimumWidth = 30;
this.colEnableState.Name = "colEnableState";
this.colEnableState.Resizable = System.Windows.Forms.DataGridViewTriState.True;
//
// colId
//
this.colId.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.colId.DataPropertyName = "ID";
this.colId.HeaderText = "ID";
this.colId.MinimumWidth = 30;
this.colId.Name = "colId";
this.colId.ReadOnly = true;
this.colId.Visible = false;
//
// colIndex
//
this.colIndex.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
this.colIndex.DataPropertyName = "Index";
this.colIndex.HeaderText = "序号";
this.colIndex.MinimumWidth = 40;
this.colIndex.Name = "colIndex";
this.colIndex.ReadOnly = true;
this.colIndex.Width = 56;
//
// colName
//
this.colName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.colName.DataPropertyName = "Name";
this.colName.FillWeight = 158.042F;
this.colName.HeaderText = "名称";
this.colName.MinimumWidth = 60;
this.colName.Name = "colName";
this.colName.ReadOnly = true;
//
// propGridElement
//
this.propGridElement.Dock = System.Windows.Forms.DockStyle.Fill;
this.propGridElement.LargeButtons = true;
this.propGridElement.LineColor = System.Drawing.SystemColors.ControlDark;
this.propGridElement.Location = new System.Drawing.Point(0, 0);
this.propGridElement.Margin = new System.Windows.Forms.Padding(3, 3, 3, 50);
this.propGridElement.Name = "propGridElement";
this.propGridElement.Size = new System.Drawing.Size(232, 248);
this.propGridElement.TabIndex = 0;
this.propGridElement.ToolbarVisible = false;
this.propGridElement.SelectedObjectsChanged += new System.EventHandler(this.propGridElement_SelectedObjectsChanged);
//
// miniToolStrip
//
this.miniToolStrip.AccessibleName = "新项选择";
this.miniToolStrip.AccessibleRole = System.Windows.Forms.AccessibleRole.ButtonDropDown;
this.miniToolStrip.AutoSize = false;
this.miniToolStrip.CanOverflow = false;
this.miniToolStrip.Dock = System.Windows.Forms.DockStyle.None;
this.miniToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.miniToolStrip.ImageScalingSize = new System.Drawing.Size(24, 24);
this.miniToolStrip.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
this.miniToolStrip.Location = new System.Drawing.Point(0, 235);
this.miniToolStrip.Margin = new System.Windows.Forms.Padding(10, 0, 0, 0);
this.miniToolStrip.Name = "miniToolStrip";
this.miniToolStrip.Size = new System.Drawing.Size(29, 237);
this.miniToolStrip.TabIndex = 1;
//
// stsStatus
//
this.stsStatus.BackColor = System.Drawing.Color.Transparent;
this.stsStatus.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsslLocation,
this.tsslMouseState});
this.stsStatus.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow;
this.stsStatus.Location = new System.Drawing.Point(0, 445);
this.stsStatus.Name = "stsStatus";
this.stsStatus.Size = new System.Drawing.Size(635, 22);
this.stsStatus.TabIndex = 0;
this.stsStatus.Text = "statusStrip1";
//
// tsslLocation
//
this.tsslLocation.Name = "tsslLocation";
this.tsslLocation.Size = new System.Drawing.Size(24, 17);
this.tsslLocation.Text = " ";
//
// tsslMouseState
//
this.tsslMouseState.Name = "tsslMouseState";
this.tsslMouseState.Size = new System.Drawing.Size(52, 17);
this.tsslMouseState.Text = " ";
//
// dataGridViewCheckBoxColumn1
//
this.dataGridViewCheckBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.dataGridViewCheckBoxColumn1.DataPropertyName = "IsEnabled";
this.dataGridViewCheckBoxColumn1.FillWeight = 41.95804F;
this.dataGridViewCheckBoxColumn1.HeaderText = "";
this.dataGridViewCheckBoxColumn1.MinimumWidth = 30;
this.dataGridViewCheckBoxColumn1.Name = "dataGridViewCheckBoxColumn1";
this.dataGridViewCheckBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.True;
//
// dataGridViewTextBoxColumn1
//
this.dataGridViewTextBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.dataGridViewTextBoxColumn1.DataPropertyName = "Id";
this.dataGridViewTextBoxColumn1.HeaderText = "ID";
this.dataGridViewTextBoxColumn1.MinimumWidth = 30;
this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1";
this.dataGridViewTextBoxColumn1.ReadOnly = true;
this.dataGridViewTextBoxColumn1.Visible = false;
//
// dataGridViewTextBoxColumn2
//
this.dataGridViewTextBoxColumn2.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader;
this.dataGridViewTextBoxColumn2.DataPropertyName = "Index";
this.dataGridViewTextBoxColumn2.HeaderText = "序号";
this.dataGridViewTextBoxColumn2.MinimumWidth = 40;
this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2";
this.dataGridViewTextBoxColumn2.ReadOnly = true;
//
// dataGridViewTextBoxColumn3
//
this.dataGridViewTextBoxColumn3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader;
this.dataGridViewTextBoxColumn3.DataPropertyName = "Name";
this.dataGridViewTextBoxColumn3.FillWeight = 158.042F;
this.dataGridViewTextBoxColumn3.HeaderText = "名称";
this.dataGridViewTextBoxColumn3.MinimumWidth = 80;
this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3";
this.dataGridViewTextBoxColumn3.ReadOnly = true;
//
// Canvas
//
this.Controls.Add(this.stsStatus);
this.Controls.Add(this.scMain);
this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134)));
this.Name = "Canvas";
this.Size = new System.Drawing.Size(635, 467);
this.ctmsElements.ResumeLayout(false);
this.ctmsKeepElements.ResumeLayout(false);
this.scMain.Panel1.ResumeLayout(false);
this.scMain.Panel1.PerformLayout();
this.scMain.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.scMain)).EndInit();
this.scMain.ResumeLayout(false);
this.tsTool.ResumeLayout(false);
this.tsTool.PerformLayout();
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.dgElements)).EndInit();
this.stsStatus.ResumeLayout(false);
this.stsStatus.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3;
private System.Windows.Forms.ContextMenuStrip ctmsElements;
private System.Windows.Forms.ToolStripMenuItem tsmiResort;
private System.Windows.Forms.ToolStripMenuItem tsmiInitialState;
private System.Windows.Forms.ToolStripMenuItem tsmiClearStandardValue;
private System.Windows.Forms.ToolStripMenuItem tsmiClearActualValue;
private System.Windows.Forms.DataGridViewCheckBoxColumn dataGridViewCheckBoxColumn1;
private System.Windows.Forms.ContextMenuStrip ctmsKeepElements;
private System.Windows.Forms.ToolStripMenuItem tsmiKeepSelected;
private System.Windows.Forms.ToolStripMenuItem tsmiKeepUnselected;
private System.Windows.Forms.ToolStripMenuItem tsmiUnselectElements;
private System.Windows.Forms.ToolStripPanel BottomToolStripPanel;
private System.Windows.Forms.ToolStripPanel TopToolStripPanel;
private System.Windows.Forms.ToolStripPanel RightToolStripPanel;
private System.Windows.Forms.ToolStripPanel LeftToolStripPanel;
private System.Windows.Forms.ToolStripContentPanel ContentPanel;
private System.Windows.Forms.SplitContainer scMain;
private System.Windows.Forms.StatusStrip stsStatus;
private System.Windows.Forms.ToolStripStatusLabel tsslLocation;
private System.Windows.Forms.ToolStripStatusLabel tsslMouseState;
private System.Windows.Forms.ToolStrip tsTool;
private System.Windows.Forms.ToolStripButton tsBtnLoadImage;
private System.Windows.Forms.ToolStripButton tsBtnSaveImage;
private System.Windows.Forms.ToolStripButton tsBtnSaveImageWithElements;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.ToolStripButton tsBtnMapSize;
private System.Windows.Forms.ToolStripButton tsBtnScreenSize;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripButton tsBtnModeNormal;
private System.Windows.Forms.ToolStripButton tsBtnModeSelection;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.CheckBox chkShowChecked;
private System.Windows.Forms.DataGridView dgElements;
private System.Windows.Forms.DataGridViewCheckBoxColumn colEnableState;
private System.Windows.Forms.DataGridViewTextBoxColumn colId;
private System.Windows.Forms.DataGridViewTextBoxColumn colIndex;
private System.Windows.Forms.DataGridViewTextBoxColumn colName;
private System.Windows.Forms.PropertyGrid propGridElement;
private System.Windows.Forms.ToolStrip miniToolStrip;
private System.Windows.Forms.ToolStrip tsROIs;
}
}

View File

@ -0,0 +1,629 @@

using DH.Commons.Enums;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static DH.Commons.Enums.EnumHelper;
namespace DH.UI.Model.Winform
{
public partial class Canvas : UserControl
{
readonly CanvasImage cvImage = new CanvasImage();
#region Grid
readonly GridCtrl gridCtrl = new GridCtrl();
private void GridValueChanged(int gridValue)
{
cvImage.GridValue = gridValue;
}
private void ShowGridChanged(bool isShowGrid)
{
cvImage.ShowGrid = isShowGrid;
}
private void GridColorChanged(Color obj)
{
cvImage.Pen_Grid.Color = obj;
}
#endregion
public Canvas()
{
InitializeComponent();
DoubleBuffered = true;
SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.AllPaintingInWmPaint, true);
cvImage.Dock = DockStyle.Fill;
scMain.Panel1.Controls.Add(cvImage);
dgElements.AutoGenerateColumns = false;
var checkHead = new DataGridViewCheckboxHeaderCell();
checkHead.OnCheckBoxClicked += CheckHead_OnCheckBoxClicked;
dgElements.Columns[0].HeaderCell = checkHead;
dgElements.Columns[0].HeaderCell.Value = string.Empty;
Elements.CollectionChanged += Elements_CollectionChanged;
cvImage.OnMouseLocationUpdated = OnMouseLocationUpdated;
cvImage.OnMouseStateChanged += OnMouseStateChanged;
gridCtrl.IsShowGridChanged = ShowGridChanged;
gridCtrl.GridValueChanged = GridValueChanged;
gridCtrl.GridColorChanged = GridColorChanged;
gridCtrl.Padding = new Padding(0, 5, 0, 5);
tsTool.Items.Add(new GridCtrlHost(gridCtrl));
tsTool.Invalidate();
_eleCollectionChangedTimer = new System.Threading.Timer(OnElementCollectionChangedBufferTimer, null, -1, -1);
//tsmiShowStatusBar.Checked = tsmiShowToolBar.Checked = IsShowElementList = IsShowROITool = IsShowStatusBar = IsShowToolBar = false;
}
private void OnMouseStateChanged(MouseState ms)
{
if (ms != MouseState.SelectionZone && ms != MouseState.SelectionZoneDoing)
{
if (this.IsHandleCreated)
{
this.Invoke(new Action(() =>
{
tsBtnModeSelection.Checked = false;
tsBtnModeNormal.Checked = true;
}));
}
}
}
#region
public bool IsShowStatusBar
{
get => stsStatus.Visible;
set => stsStatus.Visible = value;
}
private void OnMouseLocationUpdated(Point screenPoint, PointF imagePoint, string colorDesc)
{
//await Task.Run(() => tsslLocation.Text = $"屏幕坐标X{screenPoint.X}Y{screenPoint.Y} 图片坐标X{imagePoint.X}Y{imagePoint.Y} 颜色:{colorDesc}");
this.Invoke(new Action(() =>
{
tsslLocation.Text = $"屏幕坐标X{screenPoint.X}Y{screenPoint.Y} 图片坐标X{imagePoint.X.ToString("f2")}Y{imagePoint.Y.ToString("f2")} 颜色:{colorDesc}";
}));
}
//private void MouseLocationUpdated(Point screenPoint, Point imagePoint, string colorDesc)
//{
// if (InvokeRequired)
// {
// Invoke(new Action<Point, Point, string>(MouseLocationUpdated), screenPoint, imagePoint);
// }
// else
// {
// tsslLocation.Text = $"屏幕坐标X{screenPoint.X}Y{screenPoint.Y} 图片坐标X{imagePoint.X}Y{imagePoint.Y} 颜色:{colorDesc}";
// }
//}
#endregion
#region
#region CanvasImage相关
//private MouseState mouseState = MouseState.Normal;
//public MouseState MouseState
//{
// get
// {
// return mouseState;
// }
// set
// {
// if (mouseState != value)
// {
// mouseState = value;
// tsslMouseState.Text = mouseState.ToString();
// if (mouseState >= MouseState.SelectionZone)
// {
// tsBtnModeSelection.Checked = true;
// }
// else
// {
// tsBtnModeNormal.Checked = true;
// }
// }
// }
//}
public string ImageFilePath { get; set; }
public Bitmap MAP
{
get => cvImage.MAP;
set => cvImage.MAP = value;
}
public Matrix Matrix
{
get => cvImage.Matrix;
set => cvImage.Matrix = value;
}
public MouseState MouseState
{
get => cvImage.MouseState;
set => cvImage.MouseState = value;
}
public ObservableCollection<IShapeElement> Elements
{
get => cvImage.Elements;
}
#endregion
private bool isShowElementList = false;
public bool IsShowElementList
{
get => isShowElementList;
set
{
//if (isShowElementList != value)
{
isShowElementList = value;
scMain.Panel2Collapsed = !value;
}
}
}
private bool isShowROITool = false;
public bool IsShowROITool
{
get => isShowROITool;
set
{
tsROIs.Visible = isShowROITool = value;
}
}
#endregion
#region
/// <summary>
/// 载入图片
/// </summary>
/// <param name="map"></param>
public void LoadImage(Bitmap map)
{
cvImage.LoadImage(map);
OnImageChanged?.Invoke();
}
public void Clear()
{
cvImage.Clear();
}
/// <summary>
/// 设置图片为原始尺寸
/// </summary>
public void SetMapSize()
{
cvImage.SetMapSize();
}
/// <summary>
/// 设置图片为适配尺寸
/// </summary>
public void SetScreenSize()
{
cvImage.SetScreenSize();
}
#endregion
#region
private void chkShowChecked_CheckedChanged(object sender, EventArgs e)
{
dgElements.DataSource = null;
if (Elements != null && Elements.Count > 0)
{
if (chkShowChecked.Checked)
{
dgElements.DataSource = Elements.Where(u => u.IsEnabled && u.IsShowing).ToList();
}
else
{
dgElements.DataSource = Elements.Where(u => u.IsShowing).ToList();
}
}
}
private void CheckHead_OnCheckBoxClicked(object sender, DataGridViewCheckboxHeaderEventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// ele.IsEnabled = e.CheckedState;
//}
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].IsEnabled = e.CheckedState;
}
OnElementChanged(null);
}
private void dgElements_SelectionChanged(object sender, EventArgs e)
{
if (dgElements.SelectedRows.Count > 0)
{
var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());
propGridElement.SelectedObject = ele;
}
}
private void dgElements_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (dgElements.SelectedRows.Count > 0)
{
var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].State = ElementState.Normal;
}
ele.State = ElementState.Selected;
SetDeviceByElement?.Invoke(ele);
Invalidate();
}
}
System.Threading.Timer _eleCollectionChangedTimer = null;
private void OnElementCollectionChangedBufferTimer(object state)
{
OnElementChanged(null);
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].PropertyChanged -= Ele_PropertyChanged;
Elements[i].PropertyChanged += Ele_PropertyChanged;
}
//foreach (IShapeElement ele in Elements)
//{
// ele.PropertyChanged -= Ele_PropertyChanged;
// ele.PropertyChanged += Ele_PropertyChanged;
//}
}
private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//_eleCollectionChangedTimer?.Change(200, -1);
OnElementChanged(null);
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].PropertyChanged -= Ele_PropertyChanged;
Elements[i].PropertyChanged += Ele_PropertyChanged;
}
}
private void Ele_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsEnabled")
{
OnElementChanged(sender as IShapeElement);
}
else
{
Invoke(new Action(() =>
{
cvImage.Invalidate();
}));
}
}
private void OnElementChanged(IShapeElement ele)
{
if (ele != null)
OnElementChangedHandle?.Invoke(ele);
if (InvokeRequired)
{
Invoke(new Action(() => OnElementChanged(ele)));
}
else
{
if (isShowElementList)
{
dgElements.DataSource = null;
if (Elements != null && Elements.Count > 0)
{
if (chkShowChecked.Checked)
{
dgElements.DataSource = Elements.ToList().Where(u => u.IsEnabled && u.IsShowing).ToList();
}
else
{
dgElements.DataSource = Elements.ToList().Where(u => u.IsShowing).ToList();
}
}
Invalidate();
}
}
}
private void propGridElement_SelectedObjectsChanged(object sender, EventArgs e)
{
propGridElement.ExpandAllGridItems();
}
#region
private void tsmiResort_Click(object sender, EventArgs e)
{
//Elements.Sort();
}
private void tsmiClearActualValue_Click(object sender, EventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// if (ele.IsEnabled)
// {
// ele.SetActualValue(0.0);
// }
//}
}
private void tsmiInitialState_Click(object sender, EventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// if (ele.IsEnabled)
// {
// ele.State = ElementState.Normal;
// ele.InitialMeasureResult();
// }
//}
}
private void tsmiClearStandardValue_Click(object sender, EventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// if (ele.IsEnabled)
// {
// ele.SetStandardValue(0.0);
// }
//}
}
#endregion
#endregion
#region
private void tsmiKeepUnselected_Click(object sender, EventArgs e)
{
KeepElements(false);
}
private void tsmiKeepSelected_Click(object sender, EventArgs e)
{
KeepElements(true);
}
private void KeepElements(bool isKeepSelected)
{
for (int i = 0; i < Elements.Count; i++)
{
var ele = Elements[i];
if (ele.IsEnabled)
{
if (ele.State == ElementState.Selected)
{
ele.IsEnabled = isKeepSelected;
}
else
{
ele.IsEnabled = !isKeepSelected;
}
}
}
}
private void tsmiUnselectElements_Click(object sender, EventArgs e)
{
//if (MouseState == MouseState.SelectedElement)
//{
// MouseState = MouseState.Normal;
// //Elements.ForEach(ele =>
// foreach (IShapeElement ele in Elements)
// {
// ele.State = ElementState.Normal;
// }
// //);
//}
}
#endregion
#region
public Action<IShapeElement> SetElementDevicePara;
public Action<IShapeElement> SetDeviceByElement;
#endregion
#region
public bool IsShowToolBar
{
get => tsTool.Visible;
set => tsTool.Visible = value;
}
private void tsBtnLoadImage_Click(object sender, EventArgs e)
{
Thread InvokeThread = new Thread(new ThreadStart(OpenLoadImage));
InvokeThread.SetApartmentState(ApartmentState.STA);
InvokeThread.Start();
InvokeThread.Join();
}
private void OpenLoadImage()
{
ImageFilePath = "";
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
ImageFilePath = ofd.FileName;
LoadImage((Bitmap)Bitmap.FromFile(ImageFilePath));
}
}
private void tsBtnSaveImage_Click(object sender, EventArgs e)
{
if (MAP == null)
return;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
if (sfd.ShowDialog() == DialogResult.OK)
{
string filePath = sfd.FileName;
if (filePath.EndsWith("bmp"))
{
MAP.Save(filePath, ImageFormat.Bmp);
}
else
{
MAP.Save(filePath, ImageFormat.Jpeg);
}
MessageBox.Show("图片保存成功!");
}
}
private void tsBtnSaveImageWithElements_Click(object sender, EventArgs e)
{
if (MAP == null)
return;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
if (sfd.ShowDialog() == DialogResult.OK)
{
string filePath = sfd.FileName;
Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, PixelFormat.Format32bppArgb);
//Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, MAP.PixelFormat);
//Bitmap bmp = new Bitmap(MAP.Width, MAP.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.DrawImage(MAP, 0, 0);
for (int i = 0; i < Elements.Count; i++)
{
var ele = Elements[i];
if (ele.IsEnabled)
ele.Draw(g);
}
}
if (filePath.EndsWith("bmp"))
{
bmp.Save(filePath, ImageFormat.Bmp);
}
else
{
bmp.Save(filePath, ImageFormat.Jpeg);
}
MessageBox.Show("带基元图片保存成功!");
}
}
private void tsBtnMapSize_Click(object sender, EventArgs e)
{
SetMapSize();
}
private void tsBtnModeNormal_CheckedChanged(object sender, EventArgs e)
{
var btn = sender as ToolStripButton;
if (btn.Checked)
{
btn.BackColor = SystemColors.ActiveCaption;
foreach (ToolStripItem c in tsTool.Items)
{
if (c is ToolStripButton)
{
if (c.Name.StartsWith("tsBtnMode") && c.Name != btn.Name)
{
var temp = c as ToolStripButton;
temp.Checked = false;
temp.BackColor = SystemColors.Control;
}
}
}
switch (btn.Name)
{
case "tsBtnModeNormal":
MouseState = MouseState.Normal;
break;
case "tsBtnModeSelection":
MouseState = MouseState.SelectionZone;
break;
}
}
}
private void tsBtnScreenSize_Click(object sender, EventArgs e)
{
SetScreenSize();
}
#endregion
#region
//private void LoadElementTools()
//{
// var eleDict = ElementFactory.GetAllElementsInfo();
// foreach (KeyValuePair<ElementAttribute, Type> pair in eleDict)
// {
// }
//}
public void SetNewROIType(IShapeElement element)
{
cvImage.DrawTemplate = element;
}
#endregion
#region
public event Action<IShapeElement> OnElementChangedHandle;
public event Action OnImageChanged;
#endregion
#region /
private void tsmiShowToolBar_CheckedChanged(object sender, EventArgs e)
{
//IsShowToolBar = tsmiShowToolBar.Checked;
}
private void tsmiShowStatusBar_CheckedChanged(object sender, EventArgs e)
{
//IsShowStatusBar = tsmiShowStatusBar.Checked;
}
#endregion
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,33 @@
namespace DH.UI.Model.Winform
{
partial class CanvasImage
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// CanvasImage
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.Name = "CanvasImage";
this.Size = new System.Drawing.Size(575, 472);
this.ResumeLayout(false);
}
#endregion
}
}

View File

@ -0,0 +1,943 @@

using DH.Commons.Enums;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using static DH.Commons.Enums.EnumHelper;
namespace DH.UI.Model.Winform
{
public partial class CanvasImage : UserControl
{
public CanvasImage()
{
InitializeComponent();
DoubleBuffered = true;
SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.AllPaintingInWmPaint, true);
MouseWheel += Canvas_MouseWheel;
KeyDown += OnCanvasKeyDown;
KeyPress += OnCanvasKeyPressed;
MouseDoubleClick += Canvas_MouseDoubleClick;
MouseDown += Canvas_MouseDown;
MouseMove += Canvas_MouseMove;
MouseUp += Canvas_MouseUp;
// EventRouter.ChangeElementsMouseState -= OnElementChangeMouseState;
// EventRouter.ChangeElementsMouseState += OnElementChangeMouseState;
//Elements.CollectionChanged += Elements_CollectionChanged;
}
private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//this.Invoke(new Action(() =>
//{
// this.Invalidate();
//}));
}
#region Event
public Action<MouseState> OnMouseStateChanged;
public Action<IShapeElement> DrawTemplateChanged = null;
public Action<Point, PointF, string> OnMouseLocationUpdated;
#endregion
private MouseState mouseState = MouseState.Normal;
public MouseState MouseState
{
get
{
return mouseState;
}
set
{
if (mouseState != value)
{
mouseState = value;
// OnMouseStateChanged?.BeginInvoke(value, null, null);
Task.Run(() => OnMouseStateChanged.Invoke(value));
}
}
}
#region
//private Bitmap map = new Bitmap(10, 10);
//public Bitmap MAP
//{
// get
// {
// _mapLoadHandler.WaitOne();
// return map;
// }
// set
// {
// map = value;
// }
//}
public Bitmap MAP { get; set; } = new Bitmap(10, 10);
public Matrix Matrix { get; set; } = new Matrix();
public ObservableCollection<IShapeElement> Elements { get; set; } = new ObservableCollection<IShapeElement>();
RectangleF _selectionRect = new RectangleF();
#endregion
#region
protected override void OnPaint(PaintEventArgs e)
{
try
{
//lock (_mapLoadLock)
//{ }
Rectangle rect = ClientRectangle;
Graphics originG = e.Graphics;
BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
BufferedGraphics myBuffer = currentContext.Allocate(originG, rect);
Graphics g = myBuffer.Graphics;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.Clear(BackColor);
g.MultiplyTransform(Matrix);
if (MAP != null)
{
try
{
g.DrawImage(MAP, 0, 0, MAP.Width, MAP.Height);
}
catch (Exception ex)
{
}
}
else
{
g.Clear(BackColor);
}
DrawTemplate?.Draw(g);
foreach (IShapeElement ele in Elements)
{
if (ele.IsEnabled && ele.IsShowing)
{
ele.Draw(g);
}
}
#region Grid
if (MAP != null)
{
if (ShowGrid)
{
int baseX = MAP.Width / 2;
int baseY = MAP.Height / 2;
Point[] xPoint = new Point[] { new Point(0, baseY), new Point(MAP.Width, baseY) };
Point[] yPoint = new Point[] { new Point(baseX, 0), new Point(baseX, MAP.Height) };
g.DrawLine(new Pen(Pen_Grid.Color, 5.0f), xPoint[0], xPoint[1]);
g.DrawLine(new Pen(Pen_Grid.Color, 5.0f), yPoint[0], yPoint[1]);
if (GridValue > 0)
{
int stepX = MAP.Width / 2 / (GridValue * MAP.Width / 2 / _minGridStep / 10);
int stepY = MAP.Height / 2 / (GridValue * MAP.Height / 2 / _minGridStep / 10);
//int stepX = _minGridStep + (10 - GridValue) * (MAP.Width / 2 - _minGridStep) / 10;
//int stepY = _minGridStep + (10 - GridValue) * (MAP.Height / 2 - _minGridStep) / 10;
int yPositive = baseY;
do
{
xPoint = new Point[] { new Point(0, yPositive), new Point(MAP.Width, yPositive) };
g.DrawLine(Pen_Grid, xPoint[0], xPoint[1]);
yPositive -= stepY;
} while (yPositive > 0);
int yNegative = baseY;
do
{
xPoint = new Point[] { new Point(0, yNegative), new Point(MAP.Width, yNegative) };
g.DrawLine(Pen_Grid, xPoint[0], xPoint[1]);
yNegative += stepY;
} while (yNegative < MAP.Height);
int xPositive = baseX;
do
{
yPoint = new Point[] { new Point(xPositive, 0), new Point(xPositive, MAP.Height) };
g.DrawLine(Pen_Grid, yPoint[0], yPoint[1]);
xPositive -= stepX;
} while (xPositive > 0);
int xNegative = baseX;
do
{
yPoint = new Point[] { new Point(xNegative, 0), new Point(xNegative, MAP.Height) };
g.DrawLine(Pen_Grid, yPoint[0], yPoint[1]);
xNegative += stepX;
} while (xNegative < MAP.Width);
}
}
}
#endregion
if (MouseState == MouseState.SelectionZoneDoing)
{
g.DrawRectangle(Pens.AliceBlue, _selectionRect.X, _selectionRect.Y, _selectionRect.Width, _selectionRect.Height);
g.FillRectangle(new SolidBrush(Color.FromArgb(40, 0, 0, 255)), _selectionRect);
}
myBuffer.Render(originG);
g.Dispose();
myBuffer.Dispose();//释放资源
}
catch (Exception)
{
}
}
private void halfTransparent()
{
}
#endregion
#region
private IShapeElement drawTemplate = null;
public IShapeElement DrawTemplate
{
get
{
return drawTemplate;
}
set
{
if (drawTemplate != value)
{
drawTemplate = value;
//DrawTemplateChanged?.BeginInvoke(value, null, null);
Task.Run(() => DrawTemplateChanged.Invoke(value));
if (value == null)
{
MouseState = MouseState.Normal;
return;
}
MouseState = MouseState.New;
var existed = Elements.FirstOrDefault(e => e.ID == value.ID);
if (existed != null)
{
Elements.Remove(existed);
}
//if (DrawTemplate != null)
//{
// DrawTemplate.OnDrawDone += OnElementDrawDone;
//}
}
}
}
string currentElementId = "";
string CurrentElementId
{
get
{
return currentElementId;
}
set
{
if (currentElementId != value)
{
currentElementId = value;
}
}
}
private void OnElementDrawDone(IShapeElement ele)
{
//int maxIndex = 1;
//if (Elements.Count > 0)
//{
// maxIndex = Elements.Max(u => u.Index) + 1;
//}
//ele.Index = maxIndex;
//ele.Name = maxIndex.ToString();
//#region 获取基元的设备属性,目前包括运动坐标和相机参数
//SetElementDevicePara?.Invoke(ele);
//#endregion
//Elements.Add(ele);
//DrawTemplate = DrawTemplate?.Clone() as IShapeElement;
}
#endregion
#region
private void OnElementChangeMouseState(IShapeElement ele, ElementState preState, ElementState curState)
{
if (curState != ElementState.Normal)
{
switch (curState)
{
case ElementState.New:
MouseState = MouseState.New;
break;
case ElementState.Selected:
CurrentElementId = ele.ID;
Cursor = Cursors.Default;
break;
case ElementState.Moving:
MouseState = MouseState.MoveElement;
Cursor = Cursors.NoMove2D;
break;
case ElementState.Editing:
MouseState = MouseState.Editing;
Cursor = Cursors.Hand;
break;
case ElementState.MouseInSide:
MouseState = MouseState.InSideElement;
break;
case ElementState.MouseHover:
MouseState = MouseState.HoverElement;
break;
case ElementState.CanStretchLeft:
Cursor = Cursors.SizeWE;
break;
case ElementState.StretchingLeft:
MouseState = MouseState.StretchingLeft;
Cursor = Cursors.SizeWE;
break;
case ElementState.CanStretchBottom:
Cursor = Cursors.SizeNS;
break;
case ElementState.StretchingBottom:
MouseState = MouseState.StretchingBottom;
Cursor = Cursors.SizeNS;
break;
case ElementState.CanStretchRight:
Cursor = Cursors.SizeWE;
break;
case ElementState.StretchingRight:
MouseState = MouseState.StretchingRight;
Cursor = Cursors.SizeWE;
break;
case ElementState.CanStretchTop:
Cursor = Cursors.SizeNS;
break;
case ElementState.StretchingTop:
MouseState = MouseState.StretchingTop;
Cursor = Cursors.SizeNS;
break;
case ElementState.CanStretchLeftLowerCorner:
Cursor = Cursors.SizeNESW;
break;
case ElementState.StretchingLeftLowerCorner:
MouseState = MouseState.StretchingLeftLowerCorner;
Cursor = Cursors.SizeNESW;
break;
case ElementState.CanStretchLeftUpperCorner:
Cursor = Cursors.SizeNWSE;
break;
case ElementState.StretchingLeftUpperCorner:
MouseState = MouseState.StretchingLeftUpperCorner;
Cursor = Cursors.SizeNWSE;
break;
case ElementState.CanStretchRightLowerCorner:
Cursor = Cursors.SizeNWSE;
break;
case ElementState.StretchingRightLowerCorner:
MouseState = MouseState.StretchingRightLowerCorner;
Cursor = Cursors.SizeNWSE;
break;
case ElementState.CanStretchRightUpperCorner:
Cursor = Cursors.SizeNESW;
break;
case ElementState.StretchingRightUpperCorner:
MouseState = MouseState.StretchingRightUpperCorner;
Cursor = Cursors.SizeNESW;
break;
default:
//MouseState = MouseState.Normal;
break;
}
}
else
{
if (Elements.All(e => e.State == ElementState.Normal))
{
CurrentElementId = null;
if (preState == ElementState.Selected)
{
DrawTemplate = null;
}
else if (DrawTemplate != null)
{
MouseState = MouseState.New;
return;
}
//MouseState = MouseState.Normal;
}
}
this.Invalidate();
}
#endregion
#region
private void Canvas_MouseWheel(object sender, MouseEventArgs e)
{
PointF prePoint = ToMapPoint(e.Location);
//先缩放
if (e.Delta > 0)
{
Matrix.Scale((float)1.1, (float)1.1);
}
else
{
Matrix.Scale((float)0.9, (float)0.9);
}
PointF afterPoint = ToMapPoint(e.Location);
//后平移
Matrix.Translate(afterPoint.X - prePoint.X, afterPoint.Y - prePoint.Y);
Invalidate();
}
PointF startPoint, currentPoint;
bool _isMouseBtnPressing = false;
private void Canvas_MouseDown(object sender, MouseEventArgs e)
{
PointF p = ToMapPoint(e.Location);
if (e.Button == MouseButtons.Left)
{
_isMouseBtnPressing = true;
switch (MouseState)
{
case MouseState.Normal:
startPoint = e.Location;
break;
case MouseState.StretchingLeft:
break;
case MouseState.StretchingRight:
break;
case MouseState.StretchingTop:
break;
case MouseState.StretchingBottom:
break;
case MouseState.MoveElement:
break;
case MouseState.HoverElement:
case MouseState.InSideElement:
case MouseState.New:
DrawTemplate?.OnMouseDown(p);
break;
case MouseState.Editing:
break;
case MouseState.SelectionZone:
MouseState = MouseState.SelectionZoneDoing;
startPoint = p;
break;
}
foreach (IShapeElement ele in Elements)
{
ele.OnMouseDown(p);
}
}
else if (e.Button == MouseButtons.Right)
{
if (DrawTemplate != null && DrawTemplate.State == ElementState.New && DrawTemplate.IsCreatedDone())
{
IShapeElement ele = DrawTemplate.Clone() as IShapeElement;
ele.State = ElementState.Normal;
Elements.Add(ele);
// (DrawTemplate as ElementBase).Initial();
}
}
}
private void Canvas_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
return;
_isMouseBtnPressing = false;
switch (MouseState)
{
case MouseState.Normal:
break;
case MouseState.HoverElement:
break;
case MouseState.InSideElement:
break;
case MouseState.StretchingLeft:
break;
case MouseState.StretchingRight:
break;
case MouseState.StretchingTop:
break;
case MouseState.StretchingBottom:
break;
case MouseState.MoveElement:
//MouseState = MouseState.SelectedElement;
break;
case MouseState.New:
break;
case MouseState.Editing:
break;
case MouseState.MovingAll:
MouseState = MouseState.Normal;
break;
case MouseState.SelectionZone:
break;
case MouseState.SelectionZoneDoing:
MouseState = MouseState.SelectionZone;
foreach (IShapeElement ele in Elements)
{
ele.State = ElementState.Normal;
if (ele.IsIntersect(_selectionRect))
{
ele.State = ElementState.Selected;
}
}
break;
}
Cursor = Cursors.Default;
if (MouseState != MouseState.SelectionZone)
{
PointF p = ToMapPoint(e.Location);
DrawTemplate?.OnMouseUp(p);
foreach (IShapeElement ele in Elements)
{
ele.OnMouseUp(p);
}
}
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
PointF p = ToMapPoint(e.Location);
switch (MouseState)
{
case MouseState.Normal:
{
if (_isMouseBtnPressing)
{
currentPoint = e.Location;
PointF p1 = ToMapPoint(startPoint);
PointF p2 = ToMapPoint(currentPoint);
Matrix.Translate(p2.X - p1.X, p2.Y - p1.Y);
startPoint = e.Location;
}
}
break;
case MouseState.StretchingLeft:
break;
case MouseState.StretchingRight:
break;
case MouseState.StretchingTop:
break;
case MouseState.StretchingBottom:
break;
case MouseState.MoveElement:
break;
case MouseState.HoverElement:
case MouseState.InSideElement:
case MouseState.New:
DrawTemplate?.OnMouseMove(p);
break;
case MouseState.Editing:
break;
case MouseState.MovingAll:
break;
case MouseState.SelectionZoneDoing:
{
currentPoint = p;
float[] x2 = new float[2] { startPoint.X, currentPoint.X };
float[] y2 = new float[2] { startPoint.Y, currentPoint.Y };
float xMin = x2.Min();
float xMax = x2.Max();
float yMin = y2.Min();
float yMax = y2.Max();
_selectionRect = new RectangleF(xMin, yMin, xMax - xMin, yMax - yMin);
}
break;
}
PointF mapPoint = ToMapPoint(e.Location);
Color color = Color.Transparent;
if (MAP != null && mapPoint.X > 0 && mapPoint.X < MAP.Width && mapPoint.Y > 0 && mapPoint.Y < MAP.Height)
{
color = MAP.GetPixel((int)mapPoint.X, (int)mapPoint.Y);
}
// OnMouseLocationUpdated?.BeginInvoke(e.Location, mapPoint, color.Name, null, null);
Task.Run(() => OnMouseLocationUpdated?.Invoke(e.Location, mapPoint, color.Name));
if (MouseState != MouseState.SelectionZoneDoing)
{
Elements.ToList().ForEach(ele => ele?.OnMouseMove(p));
}
Invalidate();
}
private void Canvas_MouseDoubleClick(object sender, MouseEventArgs e)
{
PointF p = ToMapPoint(e.Location);
if (e.Button == MouseButtons.Left)
{
switch (MouseState)
{
//case MouseState.SelectedElement:
case MouseState.HoverElement:
case MouseState.InSideElement:
case MouseState.MoveElement:
case MouseState.Normal:
//Elements.ForEach(ele =>
foreach (IShapeElement ele in Elements)
{
ele.OnMouseDoubleClick(p);
}
//);
break;
default:
break;
}
}
else
{
//if (MouseState == MouseState.SelectedElement)
{
MouseState = MouseState.Normal;
//Elements.ForEach(ele =>
foreach (IShapeElement ele in Elements)
{
ele.State = ElementState.Normal;
}
//);
}
}
}
#endregion
#region
bool _firstLoad = true;
object _mapLoadLock = new object();
ManualResetEvent _mapLoadHandler = new ManualResetEvent(true);
ManualResetEvent _mapUsingHandler = new ManualResetEvent(false);
/// <summary>
/// 载入图片
/// </summary>
/// <param name="bitmap"></param>
public void LoadImage(Bitmap bitmap)
{
if (bitmap == null)
return;
////lock (_mapLoadLock)
////_mapUsingHandler.WaitOne();
//_mapLoadHandler.Reset();
//{
// map?.Dispose();
// map = null;
// map = bitmap;
//}
//_mapLoadHandler.Set();
MAP = bitmap;
if (_firstLoad)
{
SetScreenSize();
_firstLoad = false;
}
Invalidate();
}
public void Clear()
{
MAP = null;
Elements.Clear();
Invalidate();
}
/// <summary>
/// 设置图片为原始尺寸
/// </summary>
public void SetMapSize()
{
Matrix = new Matrix();
Invalidate();
}
/// <summary>
/// 设置图片为适配尺寸
/// </summary>
public void SetScreenSize()
{
try
{
if (MAP == null)
return;
Matrix = new Matrix();
//先缩放
List<float> ratios = new List<float>() { MAP.Width / (float)Width, MAP.Height / (float)Height };
float ratio = 1 / ratios.Max();
Matrix.Scale(ratio, ratio);
//再平移
//将plMain的中心转换为图片坐标
PointF screenCenter = new PointF(Width / 2.0f, Height / 2.0f);
PointF mapPoint = ToMapPoint(screenCenter);
//目标坐标减去当前坐标
Matrix.Translate(-MAP.Width / 2.0f + mapPoint.X, -MAP.Height / 2.0f + mapPoint.Y);
Invalidate();
}
catch (Exception ex)
{
//Trace.TraceError(ex.GetExceptionMessage());
}
}
#endregion
#region
//private void DisplayMouseLocation(Point location)
//{
// string screenPoint = string.Format("屏幕坐标X{0}Y{1}", location.X, location.Y);
// Point mapPoint = ToMapPoint(location);
// string mapPointStr = string.Format("图片坐标X{0}Y{1}", mapPoint.X, mapPoint.Y);
// tsslLocation.Text = screenPoint + " " + mapPointStr;
//}
private PointF ToMapPoint(PointF p)
{
PointF[] ps = new PointF[] { p };
Matrix invertMatrix = Matrix.Clone();
invertMatrix.Invert();
invertMatrix.TransformPoints(ps);
return ps[0];
}
private Point ToScreenPoint(Point p)
{
Point[] ps = new Point[] { p };
Matrix.TransformPoints(ps);
return ps[0];
}
#endregion
#region
public void OnCanvasKeyPressed(object sender, KeyPressEventArgs e)
{
//if (e.KeyChar == 27) //Esc
//{
// //if (MouseState == MouseState.SelectedElement)
// {
// MouseState = MouseState.Normal;
// //Elements.ForEach(ele =>
// foreach (IShapeElement ele in Elements)
// {
// ele.State = ElementState.Normal;
// }
// //);
// }
//}
//Invalidate();
}
public void OnCanvasKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete) //delete键
{
Elements.Remove(Elements.FirstOrDefault(u => u.ID == CurrentElementId));
}
if (e.KeyData == Keys.Escape) //Esc
{
if (DrawTemplate != null /*&& (DrawTemplate as ElementBase).CreatePoints.Count > 0*/)
{
DrawTemplate.Initial();
}
else
{
DrawTemplate = null;
if (MouseState != MouseState.Normal)
{
MouseState = MouseState.Normal;
}
else
{
Elements.ToList().ForEach(u => u.State = ElementState.Normal);
}
}
}
//if (e.KeyData == Keys.Up)
//{
// Elements.ToList().ForEach(u =>
// {
// if (u.State == ElementState.Selected)
// {
// u.Translate(0, -1);
// }
// });
//}
//if (e.KeyData == Keys.Down)
//{
// Elements.ToList().ForEach(u =>
// {
// if (u.State == ElementState.Selected)
// {
// u.Translate(0, 1);
// }
// });
//}
//if (e.KeyData == Keys.Left)
//{
// Elements.ToList().ForEach(u =>
// {
// if (u.State == ElementState.Selected)
// {
// u.Translate(-1, 0);
// }
// });
//}
//if (e.KeyData == Keys.Right)
//{
// Elements.ToList().ForEach(u =>
// {
// if (u.State == ElementState.Selected)
// {
// u.Translate(1, 0);
// }
// });
//}
Invalidate();
}
#endregion
#region
public Action<IShapeElement> SetElementDevicePara;
public Action<IShapeElement> SetDeviceByElement;
#endregion
#region Grid
private bool showGrid = false;
public bool ShowGrid
{
get => showGrid;
set
{
showGrid = value;
Invalidate();
}
}
private int gridValue = 0;
public int GridValue
{
get => gridValue;
set
{
gridValue = value;
Invalidate();
}
}
private Pen penGrid = new Pen(Color.FromArgb(120, Color.Red), 1.0f);
public Pen Pen_Grid
{
get => penGrid;
set
{
penGrid = value;
Invalidate();
}
}
readonly int _minGridStep = 10;
#endregion
#region Dispose
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
MAP?.Dispose();
Matrix?.Dispose();
penGrid?.Dispose();
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,109 @@
namespace DH.UI.Model.Winform
{
partial class GridCtrl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.chkShowGrid = new System.Windows.Forms.CheckBox();
this.tbGridValue = new System.Windows.Forms.TrackBar();
this.panel1 = new System.Windows.Forms.Panel();
this.colorDialog1 = new System.Windows.Forms.ColorDialog();
this.btnColor = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).BeginInit();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// chkShowGrid
//
this.chkShowGrid.Appearance = System.Windows.Forms.Appearance.Button;
//this.chkShowGrid.BackgroundImage = global::XKRS.UI.Model.Winform.Properties.Resources.grid;
this.chkShowGrid.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.chkShowGrid.Dock = System.Windows.Forms.DockStyle.Top;
this.chkShowGrid.Location = new System.Drawing.Point(0, 0);
this.chkShowGrid.Name = "chkShowGrid";
this.chkShowGrid.Size = new System.Drawing.Size(32, 30);
this.chkShowGrid.TabIndex = 0;
this.chkShowGrid.UseVisualStyleBackColor = true;
this.chkShowGrid.CheckedChanged += new System.EventHandler(this.chkShowGrid_CheckedChanged);
//
// tbGridValue
//
this.tbGridValue.AutoSize = false;
this.tbGridValue.Dock = System.Windows.Forms.DockStyle.Bottom;
this.tbGridValue.Location = new System.Drawing.Point(0, 21);
this.tbGridValue.Name = "tbGridValue";
this.tbGridValue.Orientation = System.Windows.Forms.Orientation.Vertical;
this.tbGridValue.Size = new System.Drawing.Size(32, 121);
this.tbGridValue.TabIndex = 1;
this.tbGridValue.TickStyle = System.Windows.Forms.TickStyle.Both;
this.tbGridValue.ValueChanged += new System.EventHandler(this.tbGridValue_ValueChanged);
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.Controls.Add(this.chkShowGrid);
this.panel1.Controls.Add(this.tbGridValue);
this.panel1.Location = new System.Drawing.Point(1, 1);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(32, 142);
this.panel1.TabIndex = 2;
//
// btnColor
//
this.btnColor.BackColor = System.Drawing.Color.Red;
this.btnColor.Location = new System.Drawing.Point(4, 150);
this.btnColor.Name = "btnColor";
this.btnColor.Size = new System.Drawing.Size(25, 23);
this.btnColor.TabIndex = 3;
this.btnColor.Text = " ";
this.btnColor.UseVisualStyleBackColor = false;
this.btnColor.Click += new System.EventHandler(this.btnColor_Click);
//
// GridCtrl
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
this.Controls.Add(this.btnColor);
this.Controls.Add(this.panel1);
this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134)));
this.Name = "GridCtrl";
this.Size = new System.Drawing.Size(32, 192);
((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).EndInit();
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.CheckBox chkShowGrid;
private System.Windows.Forms.TrackBar tbGridValue;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.ColorDialog colorDialog1;
private System.Windows.Forms.Button btnColor;
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace DH.UI.Model.Winform
{
public partial class GridCtrl : UserControl
{
public Action<bool> IsShowGridChanged { get; set; }
public Action<int> GridValueChanged { get; set; }
public Action<Color> GridColorChanged { get; set; }
public GridCtrl()
{
InitializeComponent();
IsChecked = chkShowGrid.Checked;
GridValue = tbGridValue.Value;
}
bool isChecked = false;
bool IsChecked
{
get => isChecked;
set
{
if (isChecked != value)
{
// IsShowGridChanged?.BeginInvoke(value, null, null);
Task.Run(() => IsShowGridChanged.Invoke(value));
}
isChecked = value;
}
}
int gridValue = 0;
int GridValue
{
get => gridValue;
set
{
if (gridValue != value)
{
// GridValueChanged?.BeginInvoke(value, null, null);
Task.Run(() => GridValueChanged.Invoke(value));
}
gridValue = value;
}
}
private void chkShowGrid_CheckedChanged(object sender, EventArgs e)
{
IsChecked = chkShowGrid.Checked;
}
private void tbGridValue_ValueChanged(object sender, EventArgs e)
{
GridValue = tbGridValue.Value;
}
private void btnColor_Click(object sender, EventArgs e)
{
if (colorDialog1.ShowDialog() == DialogResult.OK)
{
btnColor.BackColor = colorDialog1.Color;
// GridColorChanged?.BeginInvoke(btnColor.BackColor, null, null);
Task.Run(() => GridColorChanged.Invoke(btnColor.BackColor));
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,12 @@
using System.Windows.Forms;
namespace DH.UI.Model.Winform
{
public class GridCtrlHost : ToolStripControlHost
{
public GridCtrlHost(GridCtrl grid) : base(grid)
{
//Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, 134);
}
}
}

View File

@ -0,0 +1,78 @@
namespace DH.UI.Model.Winform
{
partial class IOIndicatorCtrl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
plStatus = new Panel();
lblDesc = new Label();
SuspendLayout();
//
// plStatus
//
plStatus.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left;
plStatus.Location = new Point(0, 0);
plStatus.Margin = new Padding(4);
plStatus.Name = "plStatus";
plStatus.Size = new Size(28, 34);
plStatus.TabIndex = 0;
plStatus.Paint += plStatus_Paint;
plStatus.DoubleClick += plStatus_DoubleClick;
//
// lblDesc
//
lblDesc.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
lblDesc.AutoSize = true;
lblDesc.Font = new Font("Tahoma", 11F, FontStyle.Regular, GraphicsUnit.World);
lblDesc.Location = new Point(36, 11);
lblDesc.Margin = new Padding(4, 0, 4, 0);
lblDesc.Name = "lblDesc";
lblDesc.Size = new Size(31, 13);
lblDesc.TabIndex = 1;
lblDesc.Text = "XXXX";
lblDesc.TextAlign = ContentAlignment.MiddleLeft;
lblDesc.DoubleClick += lblDesc_DoubleClick;
//
// IOIndicatorCtrl
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(lblDesc);
Controls.Add(plStatus);
Margin = new Padding(4);
Name = "IOIndicatorCtrl";
Size = new Size(138, 34);
ResumeLayout(false);
PerformLayout();
}
#endregion
private Panel plStatus;
private Label lblDesc;
}
}

View File

@ -0,0 +1,126 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace DH.UI.Model.Winform
{
public partial class IOIndicatorCtrl : UserControl
{
public IOIndicatorCtrl()
{
InitializeComponent();
}
private bool isON = false;
public bool IsOn
{
get => isON;
set
{
bool? temp = isON;
isON = value;
if (temp != isON)
{
RefreshStatus();
}
}
}
private void RefreshStatus()
{
if (InvokeRequired)
{
Invoke(new Action(() => RefreshStatus()));
}
else
{
plStatus.Invalidate();
}
}
private string desc = "";
public string Desc
{
get => desc;
set
{
desc = value;
DisplayDesc();
}
}
public int Index { get; set; }
private void DisplayDesc()
{
if (InvokeRequired)
{
Invoke(new Action(() => DisplayDesc()));
}
else
{
lblDesc.Text = Desc;
}
}
readonly PointF[] regionBlink = new PointF[]
{
new PointF(5,10),
new PointF(10,13),
new PointF(12,7),
new PointF(10,5)
};
public IOIndicatorCtrl(bool _isOn, string _desc, int index = 0)
{
InitializeComponent();
IsOn = _isOn;
Desc = _desc;
Index = index;
}
/// <summary>
/// 更新绘制图标
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void plStatus_Paint(object sender, PaintEventArgs e)
{
Panel pl = sender as Panel;
Graphics g = e.Graphics;
g.Clear(SystemColors.Control);
if (IsOn)
{
g.FillEllipse(Brushes.LightGreen, pl.ClientRectangle);
}
else
{
g.FillEllipse(Brushes.Gray, pl.ClientRectangle);
}
g.FillPolygon(Brushes.White, regionBlink);
}
public event Action<string, bool, int> OnIODoubleClick;
private void lblDesc_DoubleClick(object sender, EventArgs e)
{
OnIODoubleClick?.Invoke(Name, IsOn, Index);
}
private void plStatus_DoubleClick(object sender, EventArgs e)
{
OnIODoubleClick?.Invoke(Name, IsOn, Index);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,48 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<BaseOutputPath>..\</BaseOutputPath>
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
<UseWindowsForms>true</UseWindowsForms>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
<Generator>SettingsSingleFileGenerator</Generator>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,199 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using static DH.Commons.Enums.EnumHelper;
namespace DH.UI.Model.Winform
{
//public static class AOIEnumHelper
//{
// public enum ElementState
// {
// New = 1,
// MouseHover = 2,
// MouseInSide = 3,
// Selected = 4,
// Moving = 5,
// Normal = 11,
// Measuring = 21,
// MeasureDoneOK = 22,
// MeasureDoneNG = 23,
// }
// public enum MouseState
// {
// Normal = 1,
// HoverElement = 2,
// InSideElement = 3,
// StretchingLeft = 11,
// StretchingRight = 12,
// StretchingUp = 13,
// StretchingDown = 14,
// MoveElement = 15,
// New = 21,
// Editing = 22,
// SelectedElement = 23,
// MovingAll = 31,
// SelectionZone = 41,
// SelectionZoneDoing = 42,
// }
// public enum RunMode
// {
// [Description("设置模式")]
// SetMode = 0,
// [Description("运行模式")]
// RunMode = 1,
// }
//}
public static class EventRouter
{
/// <summary>
/// ElementBase 基元
/// 1st MouseState 初始状态
/// 2nd MouseState 变化状态
/// </summary>
public static event Action<ElementBase, ElementState, ElementState> ChangeElementsMouseState;
public static void TriggerElementsMouseStateChanged(ElementBase ele, ElementState preState, ElementState curState)
{
ChangeElementsMouseState?.Invoke(ele, preState, curState);
}
}
public class NoticedPoints : List<PointF>
{
public Action OnItemChanged;
public NoticedPoints() { }
public NoticedPoints(List<PointF> points)
{
AddRange(points);
}
public new PointF this[int index]
{
get
{
if (index >= 0 && index < Count)
{
return base[index];
}
else
{
return new Point();
}
}
set
{
if (base[index] != value)
{
base[index] = value;
OnItemChanged?.Invoke();
}
}
}
public new void Add(PointF item)
{
lock (this)
{
base.Add(item);
OnItemChanged?.Invoke();
}
}
public new void AddRange(IEnumerable<PointF> collection)
{
lock (this)
{
base.AddRange(collection);
OnItemChanged?.Invoke();
}
}
public new void Clear()
{
lock (this)
{
base.Clear();
OnItemChanged?.Invoke();
}
}
public new void Insert(int index, PointF item)
{
lock (this)
{
base.Insert(index, item);
OnItemChanged?.Invoke();
}
}
public new void InsertRange(int index, IEnumerable<PointF> collection)
{
lock (this)
{
base.InsertRange(index, collection);
OnItemChanged?.Invoke();
}
}
public new bool Remove(PointF item)
{
lock (this)
{
bool flag = base.Remove(item);
if (flag)
{
OnItemChanged?.Invoke();
}
return flag;
}
}
public new int RemoveAll(Predicate<PointF> match)
{
lock (this)
{
int i = base.RemoveAll(match);
if (i > 0)
{
OnItemChanged?.Invoke();
}
return i;
}
}
public new void RemoveAt(int index)
{
lock (this)
{
base.RemoveAt(index);
OnItemChanged?.Invoke();
}
}
public new void RemoveRange(int index, int count)
{
lock (this)
{
base.RemoveRange(index, count);
OnItemChanged?.Invoke();
}
}
}
}

View File

@ -0,0 +1,980 @@

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.Json.Serialization;
using DH.Commons.Enums;
using static DH.Commons.Enums.EnumHelper;
namespace DH.UI.Model.Winform
{
[Serializable]
public abstract class ElementBase : IShapeElement, IEventHandle, ICloneable, IComparable<ElementBase>, IDisposable
{
#region
protected int _mouseIntersectDistance = 4;
#endregion
#region
/// <summary>
/// ID采用GUID
/// </summary>
[ReadOnly(true)]
[Category("\t通用标识")]
[Description("GUID")]
public virtual string ID { get; set; } = Guid.NewGuid().ToString().ToUpper();
/// <summary>
/// 序号
/// </summary>
[Category("\t通用标识")]
[Description("序号")]
public virtual int Index { get; set; } = 0;
[Browsable(false)]
public virtual int GroupIndex { get; set; } = 0;
private string name = "";
/// <summary>
/// 名称
/// </summary>
[Category("\t通用标识")]
[Description("名称")]
public virtual string Name
{
get
{
if (string.IsNullOrWhiteSpace(name))
{
return GetDisplayText();
}
else
{
return name;
}
}
set => name = value;
}
#endregion
#region
private bool isEnabled = true;
//[Browsable(false)]
public virtual bool IsEnabled
{
get
{
return isEnabled;
}
set
{
//if (isEnabled != value)
//{
// isEnabled = value;
// PropertyChanged?.BeginInvoke(this, new PropertyChangedEventArgs("IsEnabled"), null, null);
//}
Set(ref isEnabled, value);
}
}
[Browsable(false)]
public virtual bool IsShowing { get; set; } = true;
private bool showList = true;
[Browsable(false)]
public virtual bool ShowList
{
get => showList;
set => Set(ref showList, value);
}
#endregion
#region
[JsonIgnore]
protected PointF _startPoint, _currentPoint;
#endregion
#region
[Browsable(false)]
public NoticedPoints CreatePoints { get; set; } = new NoticedPoints();
public virtual bool IsCreatedDone()
{
return CreatePoints.Count >= 2;
}
//protected Region Region { get; set; }
#region
#region
[JsonIgnore]
[Browsable(false)]
protected Pen Pen { get; set; } = new Pen(Color.Red, 1);
protected virtual void SetNewStatePen()
{
Pen = new Pen(Color.Red, 3);
}
protected virtual void SetNormalPen()
{
Pen = new Pen(Color.Red, 1);
}
protected virtual void SetHoverPen()
{
Pen = new Pen(Color.BlueViolet, 3);
}
protected virtual void SetInSidePen()
{
Pen = new Pen(Color.YellowGreen, 3);
}
protected virtual void SetSelectedPen()
{
Pen = new Pen(Color.Pink, 3);
}
protected virtual void SetMeasureDoneOKPen()
{
Pen = new Pen(Color.Green, 2);
}
protected virtual void SetMeasureDoneNGPen()
{
Pen = new Pen(Color.Red, 2);
}
protected virtual void SetMeasuringPen()
{
Pen = new Pen(Color.Yellow, 3);
}
#endregion
#region
//[JsonIgnore]
//protected Pen PenText = new Pen(Color.Black, 1);
//[JsonIgnore]
//protected Pen PenTextOK = new Pen(Color.Green, 1.5f);
//[JsonIgnore]
//protected Pen PenTextNG = new Pen(Color.Red, 2);
///// <summary>
///// 字体大小
///// </summary>
//[Category("显示属性")]
//[Description("字体大小")]
////[Browsable(false)]
//public virtual float FontSize { get; set; } = 15;
/// <summary>
/// 字体大小
/// </summary>
[Category("显示属性")]
[Description("字体设置")]
[Browsable(false)]
public virtual Font Font { get; set; } = new Font(new FontFamily("Tahoma"), 15, GraphicsUnit.World);
/// <summary>
/// 字体和基元的距离
/// </summary>
[Category("显示属性")]
[Description("字体和基元的距离")]
[Browsable(false)]
public virtual int FontDistance { get; set; } = 15;
[Category("显示属性")]
[Description("显示字符说明")]
[Browsable(false)]
public virtual bool IsShowRemark { get; set; } = true;
#endregion
#endregion
//public Graphics Graphics { get; set; }
public abstract void Draw(Graphics g);
protected abstract void DrawResult(Graphics g);
#endregion
#region
private ElementState state = ElementState.New;
[JsonIgnore]
[Browsable(false)]
public ElementState State
{
get
{
return state;
}
set
{
if (state != value)
{
ElementState preState = state;
Set(ref state, value);
EventRouter.TriggerElementsMouseStateChanged(this, preState, state);
switch (state)
{
case ElementState.MouseHover:
SetHoverPen();
break;
case ElementState.MouseInSide:
SetInSidePen();
break;
case ElementState.Selected:
SetSelectedPen();
break;
case ElementState.Normal:
SetNormalPen();
break;
case ElementState.Measuring:
SetMeasuringPen();
break;
case ElementState.MeasureDoneOK:
SetMeasureDoneOKPen();
break;
case ElementState.MeasureDoneNG:
SetMeasureDoneNGPen();
break;
case ElementState.New:
SetNewStatePen();
break;
}
}
}
}
/// <summary>
/// 是否是运行模式
/// </summary>
[Browsable(false)]
public RunMode RunMode { get; set; } = RunMode.NormalMode;
#endregion
#region
public abstract object Clone();
public virtual void Initial()
{
State = ElementState.New;
CreatePoints = new NoticedPoints();
}
#endregion
#region IMouseEvent
public virtual void OnMouseDoubleClick(PointF p)
{
if (State == ElementState.MeasureDoneNG || State == ElementState.MeasureDoneOK)
return;
//if (State == ElementState.MouseInSide)
//{
// State = ElementState.Selected;
//}
//else if (State == ElementState.Selected || State == ElementState.Moving)
//{
// if (IsMouseInSide(p))
// {
// State = ElementState.MouseInSide;
// }
//}
if (IsMouseInSide(p))
{
State = ElementState.Selected;
}
}
public abstract void OnKeyDown(object sender, KeyEventArgs e);
public abstract void OnKeyUp(object sender, KeyEventArgs e);
public virtual void OnMouseDown(PointF p)
{
//switch (State)
//{
// case ElementState.New:
// OnMouseDownWhenNew(p);
// break;
// case ElementState.MouseHover:
// break;
// case ElementState.MouseInSide:
// State = ElementState.Selected;
// break;
// case ElementState.Selected:
// _startPoint = p;
// State = ElementState.Moving;
// break;
// case ElementState.Normal:
// break;
//}
if (State == ElementState.New)
{
OnMouseDownWhenNew(p);
}
else if (IsMouseCanMoveElement(p) && State == ElementState.Selected)
{
State = ElementState.Moving;
}
else if (IsMouseCanStretchBottom(p) && State == ElementState.CanStretchBottom)
{
State = ElementState.StretchingBottom;
}
else if (IsMouseCanStretchTop(p) && State == ElementState.CanStretchTop)
{
State = ElementState.StretchingTop;
}
else if (IsMouseCanStretchLeft(p) && State == ElementState.CanStretchLeft)
{
State = ElementState.StretchingLeft;
}
else if (IsMouseCanStretchRight(p) && State == ElementState.CanStretchRight)
{
State = ElementState.StretchingRight;
}
else if (IsMouseCanStretchLeftLowerCorner(p) && State == ElementState.CanStretchLeftLowerCorner)
{
State = ElementState.StretchingLeftLowerCorner;
}
else if (IsMouseCanStretchLeftUpperCorner(p) && State == ElementState.CanStretchLeftUpperCorner)
{
State = ElementState.StretchingLeftUpperCorner;
}
else if (IsMouseCanStretchRightLowerCorner(p) && State == ElementState.CanStretchRightLowerCorner)
{
State = ElementState.StretchingRightLowerCorner;
}
else if (IsMouseCanStretchRightUpperCorner(p) && State == ElementState.CanStretchRightUpperCorner)
{
State = ElementState.StretchingRightUpperCorner;
}
}
public virtual void OnMouseMove(PointF p)
{
switch (State)
{
case ElementState.New:
OnMouseMoveWhenNew(p);
break;
case ElementState.Selected:
{
if (IsMouseCanStretchLeft(p))
{
State = ElementState.CanStretchLeft;
}
else if (IsMouseCanStretchRight(p))
{
State = ElementState.CanStretchRight;
}
else if (IsMouseCanStretchTop(p))
{
State = ElementState.CanStretchTop;
}
else if (IsMouseCanStretchBottom(p))
{
State = ElementState.CanStretchBottom;
}
else if (IsMouseCanStretchLeftLowerCorner(p))
{
State = ElementState.CanStretchLeftLowerCorner;
}
else if (IsMouseCanStretchLeftUpperCorner(p))
{
State = ElementState.CanStretchLeftUpperCorner;
}
else if (IsMouseCanStretchRightLowerCorner(p))
{
State = ElementState.CanStretchRightLowerCorner;
}
else if (IsMouseCanStretchRightUpperCorner(p))
{
State = ElementState.CanStretchRightUpperCorner;
}
break;
}
case ElementState.Moving:
_currentPoint = p;
//Translate(_currentPoint.X - _startPoint.X, _currentPoint.Y - _startPoint.Y);
//_startPoint = _currentPoint;
Relocate(p);
break;
case ElementState.MouseHover:
case ElementState.MouseInSide:
case ElementState.Normal:
//if (IsMouseInSide(p))
//{
// State = ElementState.MouseInSide;
//}
//else if (IsMouseHover(p))
//{
// State = ElementState.MouseHover;
//}
//else
//{
// State = ElementState.Normal;
//}
break;
case ElementState.CanStretchBottom:
if (!IsMouseCanStretchBottom(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchTop:
if (!IsMouseCanStretchTop(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchLeft:
if (!IsMouseCanStretchLeft(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchRight:
if (!IsMouseCanStretchRight(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchLeftUpperCorner:
if (!IsMouseCanStretchLeftUpperCorner(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchLeftLowerCorner:
if (!IsMouseCanStretchLeftLowerCorner(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchRightLowerCorner:
if (!IsMouseCanStretchRightLowerCorner(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchRightUpperCorner:
if (!IsMouseCanStretchRightUpperCorner(p))
{
State = ElementState.Selected;
}
break;
case ElementState.StretchingTop:
StretchTop(p);
break;
case ElementState.StretchingBottom:
StretchBottom(p);
break;
case ElementState.StretchingLeft:
StretchLeft(p);
break;
case ElementState.StretchingRight:
StretchRight(p);
break;
case ElementState.StretchingLeftLowerCorner:
StretchLeftLowerCorner(p);
break;
case ElementState.StretchingLeftUpperCorner:
StretchLeftUpperCorner(p);
break;
case ElementState.StretchingRightLowerCorner:
StretchRightLowerCorner(p);
break;
case ElementState.StretchingRightUpperCorner:
StretchRightUpperCorner(p);
break;
}
}
public virtual void OnMouseUp(PointF p)
{
switch (State)
{
case ElementState.New:
OnMouseUpWhenNew(p);
break;
case ElementState.Moving:
State = ElementState.Selected;
break;
case ElementState.Selected:
if (!IsMouseInSide(p))
{
State = ElementState.Normal;
}
break;
case ElementState.StretchingBottom:
State = ElementState.CanStretchBottom;
break;
case ElementState.StretchingLeft:
State = ElementState.CanStretchLeft;
break;
case ElementState.StretchingRight:
State = ElementState.CanStretchRight;
break;
case ElementState.StretchingTop:
State = ElementState.CanStretchTop;
break;
case ElementState.StretchingLeftLowerCorner:
State = ElementState.CanStretchLeftLowerCorner;
break;
case ElementState.StretchingLeftUpperCorner:
State = ElementState.CanStretchLeftUpperCorner;
break;
case ElementState.StretchingRightUpperCorner:
State = ElementState.CanStretchRightUpperCorner;
break;
case ElementState.StretchingRightLowerCorner:
State = ElementState.CanStretchRightLowerCorner;
break;
default:
State = ElementState.Normal;
break;
}
AfterTranformOp();
}
public virtual void AfterTranformOp()
{
}
#region
/// <summary>
/// 当状态为New时的鼠标按下操作
/// </summary>
/// <param name="p"></param>
public abstract void OnMouseDownWhenNew(PointF p);
public abstract void OnMouseMoveWhenNew(PointF p);
public abstract void OnMouseUpWhenNew(PointF p);
#endregion
#endregion
#region
[JsonIgnore]
public Action<ElementBase> OnDrawDone;
[JsonIgnore]
public Action<ElementBase> OnMeasureDone;
[JsonIgnore]
public Action<ElementBase> OnElementEnableChanged;
#endregion
#region
/// <summary>
/// 基类基础的Rectangle 用于计算MouseHover和Inside等
/// </summary>
[Browsable(false)]
public Rectangle BaseRectangle { get; set; }
EnumHelper.ElementState IShapeElement.State { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public abstract bool IsMouseHover(PointF p);
public abstract bool IsMouseInSide(PointF p);
public abstract bool IsIntersect(RectangleF rect);
#region Move & Stretch & Move Anchor
public virtual bool IsMouseCanMoveElement(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchLeft(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchRight(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchTop(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchBottom(PointF p)
{
return false;
}
public virtual void StretchLeft(PointF p)
{
}
public virtual void StretchRight(PointF p)
{
}
public virtual void StretchTop(PointF p)
{
}
public virtual void StretchBottom(PointF p)
{
}
public virtual bool IsMouseCanStretchLeftUpperCorner(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchRightUpperCorner(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchLeftLowerCorner(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchRightLowerCorner(PointF p)
{
return false;
}
public virtual void StretchLeftUpperCorner(PointF p)
{
}
public virtual void StretchRightUpperCorner(PointF p)
{
}
public virtual void StretchLeftLowerCorner(PointF p)
{
}
public virtual void StretchRightLowerCorner(PointF p)
{
}
public virtual bool IsMouseCanMoveAnchor(PointF p)
{
return false;
}
#endregion
#endregion
#region
public abstract void Translate(float x, float y);
public virtual void Relocate(PointF point) { }
//public abstract void RotateAt(int x, int y, float degree);
#endregion
#region
//[Browsable(false)]
//public PlanPoint MovePoint { get; set; }
#endregion
#region
//[Browsable(false)]
//public CameraOperationConfigBase CameraOpConfig { get; set; }
#endregion
#region
#endregion
#region
/// <summary>
/// 算法
/// </summary>
/// <param name="paras">计算参数</param>
public virtual void Calculate(Bitmap image) { }
public virtual void Calculate(IntPtr imagePtr, int ptrSize, int imageWidth, int imageHeight) { }
public virtual void Calculate(string imagePath) { }
#endregion
#region
//[Description("图片保存方式")]
//public ImageSaveMode ImageSaveMode { get; set; } = ImageSaveMode.NoSave;
//public virtual void SaveImage(Bitmap image)
//{
// if (string.IsNullOrWhiteSpace(AOIMeasure.GlobalVar.ImageSaveDirectory) || ImageSaveMode == ImageSaveMode.NoSave)
// {
// return;
// }
// DirectoryInfo dir = new DirectoryInfo(GlobalVar.ImageSaveDirectory);
// if (!dir.Exists)
// {
// dir.Create();
// }
// string imgPath = Path.Combine(AOIMeasure.GlobalVar.ImageSaveDirectory, Name + "_" + DateTime.Now.ToString("MMdd_HHmmss") + ".bmp");
// switch (ImageSaveMode)
// {
// case ImageSaveMode.SaveImage:
// image.Save(imgPath);
// break;
// case ImageSaveMode.SaveImageWithElement:
// Bitmap bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb);
// using (Graphics g = Graphics.FromImage(bmp))
// {
// g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
// g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
// g.DrawImage(image, 0, 0, image.Width, image.Height);
// Draw(g);
// }
// bmp.Save(imgPath);
// break;
// }
//}
//public virtual void SaveImage(IntPtr imagePtr, int ptrSize)
//{
// Bitmap map = null;
// unsafe
// {
// byte* pArray = (byte*)imagePtr;
// byte[] array = new byte[ptrSize];
// Marshal.Copy(imagePtr, array, 0, ptrSize);
// using (MemoryStream ms = new MemoryStream(array))
// {
// map = (Bitmap)Image.FromStream(ms);
// }
// }
// SaveImage(map);
//}
//public virtual void SaveImage(string imagePath)
//{
// using (Bitmap map = Image.FromFile(imagePath) as Bitmap)
// {
// SaveImage(map);
// }
//}
#endregion
#region
public virtual void InitialMeasureResult()
{
//PropertyInfo[] prop = this.GetType().GetProperties();
//Array.ForEach(prop, p =>
//{
// if ((p.PropertyType.Name == typeof(MeasureSpec).Name) && p.CanRead && p.CanWrite)
// {
// MeasureSpec spec = p.GetValue(this) as MeasureSpec;
// spec.Result = MeasureResult.NotYet;
// p.SetValue(this, spec);
// }
//});
}
public virtual void SetActualValue(double v)
{
//PropertyInfo[] prop = this.GetType().GetProperties();
//Array.ForEach(prop, p =>
// {
// if ((p.PropertyType.Name == typeof(MeasureSpec).Name) && p.CanRead && p.CanWrite)
// {
// MeasureSpec spec = p.GetValue(this) as MeasureSpec;
// spec.ActualValue = (float)v;
// p.SetValue(this, spec);
// }
// });
}
public virtual void SetStandardValue(double v)
{
//PropertyInfo[] prop = this.GetType().GetProperties();
//Array.ForEach(prop, p =>
//{
// if ((p.PropertyType.Name == typeof(MeasureSpec).Name) && p.CanRead && p.CanWrite)
// {
// MeasureSpec spec = p.GetValue(this) as MeasureSpec;
// spec.StandardValue = (float)v;
// p.SetValue(this, spec);
// }
//});
}
#endregion
#region IPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public virtual void Set<T>(ref T field, T newValue, [CallerMemberName] string propName = null)
{
if (!field.Equals(newValue))
{
field = newValue;
//PropertyChanged?.BeginInvoke(this, new PropertyChangedEventArgs(propName), null, null);
RaisePropertyChanged(propName);
}
}
public virtual void RaisePropertyChanged(string propName = "")
{
//PropertyChanged?.BeginInvoke(this, new PropertyChangedEventArgs(propName), null, null);
//Task.Run(() =>
//{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
//});
}
#endregion
public override string ToString()
{
return GetDisplayText();
}
public abstract string GetDisplayText();
#region IComparable
public virtual int CompareTo(ElementBase other)
{
//throw new NotImplementedException();
return Index - other.Index;
}
#endregion
#region IDisposable Support
private bool disposedValue = false; // 要检测冗余调用
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// 释放托管状态(托管对象)。
Pen?.Dispose();
}
// TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
// TODO: 将大型字段设置为 null。
disposedValue = true;
}
}
// TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
// ~ElementBase()
// {
// // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
// Dispose(false);
// }
// 添加此代码以正确实现可处置模式。
public void Dispose()
{
// 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
Dispose(true);
// TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
// GC.SuppressFinalize(this);
}
#endregion
}
[Serializable]
public abstract class DisplayElementBase : ElementBase
{
//public override object Clone()
//{
// throw new NotImplementedException();
//}
//public override void Draw(Graphics g)
//{
// throw new NotImplementedException();
//}
//public override string GetDisplayText()
//{
// throw new NotImplementedException();
//}
//public override bool IsIntersect(Rectangle rect)
//{
// throw new NotImplementedException();
//}
public override bool IsMouseHover(PointF p)
{
return false;
}
//public override bool IsMouseInSide(Point p)
//{
// throw new NotImplementedException();
//}
public override void OnKeyDown(object sender, KeyEventArgs e)
{
}
public override void OnKeyUp(object sender, KeyEventArgs e)
{
}
public override void OnMouseDownWhenNew(PointF p)
{
}
public override void OnMouseMoveWhenNew(PointF p)
{
}
public override void OnMouseUpWhenNew(PointF p)
{
}
public override void Translate(float x, float y)
{
}
protected override void DrawResult(Graphics g)
{
}
}
public interface IEventHandle
{
void OnMouseMove(PointF p);
void OnMouseDown(PointF p);
void OnMouseUp(PointF p);
void OnMouseDoubleClick(PointF p);
void OnKeyDown(object sender, KeyEventArgs e);
void OnKeyUp(object sender, KeyEventArgs e);
}
public class ElementIndexCompare : IComparer<ElementBase>
{
public int Compare(ElementBase x, ElementBase y)
{
return x.Index - y.Index;
}
}
}

View File

@ -0,0 +1,325 @@

using DH.Commons.Enums;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DH.UI.Model.Winform
{
public class DetectResultDisplay : ElementBase
{
//深度学习 显示结果
private List<DetectionResultDetail> mlResultList = null;
public List<DetectionResultDetail> MLResultList
{
get => mlResultList;
set
{
if (mlResultList != value)
{
mlResultList = value;
}
}
}
//测量结果
//private List<IndexedSpec> specResultList = null;
//public List<IndexedSpec> SpecResultList
//{
// get => specResultList;
// set
// {
// if (specResultList != value)
// {
// specResultList = value;
// string specDisplay = "";
// if (specResultList != null && specResultList.Count > 0)
// {
// specResultList.ForEach(s =>
// {
// specDisplay += $"{s.Code}:{(s.ActualValue ?? 0).ToString("f2")}\r\n";
// });
// }
// if (!string.IsNullOrWhiteSpace(specDisplay))
// {
// DisplayTxt += specDisplay;
// }
// }
// }
//}
ResultState ResultState = ResultState.DetectNG;
string DisplayTxt = "";
Bitmap ResultImage = null;
PointF StartPoint = new PointF();
Brush FontBrush = new SolidBrush(Color.Green);
Pen DetectResultRectPen = new Pen(new SolidBrush(Color.Green));
Font DetectResultFont = new Font(new FontFamily("Tahoma"), 15, GraphicsUnit.World);
public int ImageWidth { get; set; }
public int ImageHeight { get; set; }
public DetectResultDisplay() { }
//public DetectResultDisplay(NetResult result, List<IndexedSpec> specs, ResultState resultState, int imageWidth)
//{
// ImageWidth = imageWidth;
// ResultState = resultState;
// displayTxt = resultState.ToString() + "\r\n";
// if (resultState != ResultState.OK)
// {
// fontBrush = new SolidBrush(Color.Red);
// }
// NetResult = result;
// SpecList = specs;
// Font = new Font(new FontFamily("Tahoma"), 35 * ImageWidth / 1400, GraphicsUnit.World);
// startPoint = new PointF(150 * ImageWidth / 1400, 150 * ImageWidth / 1400);
//}
public DetectResultDisplay(DetectStationResult detectResult, Bitmap resultImage, string displayTxt)
{
ImageWidth = resultImage.Width;
ImageHeight = resultImage.Height;
var longSide = ImageWidth > ImageHeight ? ImageWidth : ImageHeight;
MLResultList = detectResult.DetectDetails;
// SpecResultList = detectResult.Specs;
ResultState = detectResult.ResultState;
ResultImage = resultImage;
DisplayTxt = displayTxt;
if (ResultState != ResultState.OK)
{
FontBrush = new SolidBrush(Color.Red);
DetectResultRectPen = new Pen(new SolidBrush(Color.Red));
}
Font = new Font(new FontFamily("Tahoma"), 35 * longSide / 1400, GraphicsUnit.World);
DetectResultFont = new Font(new FontFamily("Tahoma"), 25 * longSide / 1400, GraphicsUnit.World);
StartPoint = new PointF(100 * ImageWidth / 1400, 100 * ImageHeight / 1400);
}
public override object Clone()
{
return null;
}
public override void Draw(Graphics g)
{
//画检测结果图
if (ResultImage != null && ResultState != ResultState.OK)
{
g.DrawImage(ResultImage, new Point(0, 0));
}
//画文字
if (!string.IsNullOrWhiteSpace(DisplayTxt))
{
g.DrawString(DisplayTxt, Font, FontBrush, StartPoint);
}
//画外接矩形+label 深度学习
if (MLResultList != null && MLResultList.Count > 0)
{
MLResultList.ForEach(d =>
{
g.DrawRectangle(DetectResultRectPen, d.Rect);
string locationTxt = $"{d.LabelDisplay}";
var locationX = d.Rect.X;
var locationY = d.Rect.Y <= 20 ? d.Rect.Y + 20 : d.Rect.Y - 20;
g.DrawString(locationTxt, DetectResultFont, FontBrush, locationX, locationY);
});
}
//画spec信息
//if (DetectResult != null && DetectResult.NetResult?.DetectDetails?.Count > 0)
//{
// DetectResult.NetResult?.DetectDetails.ForEach(d =>
// {
// g.DrawRectangle(defectRectPen, d.Rect);
// string locationTxt = $"{d.Rect.X},{d.Rect.Y}";
// g.DrawString(locationTxt, defectFont, fontBrush, d.Rect.X, d.Rect.Y - 5);
// });
//}
//float fontHeight = g.MeasureString(displayTxt, Font).Height;
//startPoint.Y += fontHeight * 1.2f;
//var defects = DetectResult.NetResult?.DetectDetails;
//if (defects != null && defects.Count > 0)
//{
// defects.ForEach(d =>
// {
// g.DrawString($"{d.ClassName} X:{d.Rect.X.ToString("f2")} Y:{d.Rect.Y.ToString("f2")} S:{d.Area}", Font, d.FinalResult == EnumHelper.ResultState.OK ? fontBrushOK : fontBrushNG, startPoint);
// startPoint.Y += fontHeight;
// });
//}
//DetectResult.Specs.ForEach(s =>
//{
// g.DrawString($"{s.Code}:{(s.ActualValue ?? 0).ToString("f2")}", Font, s.MeasureResult ?? false == true ? fontBrushOK : fontBrushNG, startPoint);
// startPoint.Y += fontHeight;
//});
}
public override string GetDisplayText()
{
return "";
}
public override bool IsIntersect(RectangleF rect)
{
return false;
}
public override bool IsMouseHover(PointF p)
{
return false;
}
public override bool IsMouseInSide(PointF p)
{
return false;
}
public override void OnKeyDown(object sender, KeyEventArgs e)
{
}
public override void OnKeyUp(object sender, KeyEventArgs e)
{
}
protected override void DrawResult(Graphics g)
{
}
public override void OnMouseDownWhenNew(PointF p)
{
}
public override void OnMouseMoveWhenNew(PointF p)
{
}
public override void OnMouseUpWhenNew(PointF p)
{
}
public override void Translate(float x, float y)
{
}
}
public class RectResultDisplay : ElementBase
{
ResultState ResultState = ResultState.DetectNG;
public string DisplayTxt = "";
Color FillColor = Color.Lime;
int FontSize = 15;
RectangleF Rect = new RectangleF();
bool IsFilled = false;
public RectResultDisplay() { }
public RectResultDisplay(ResultState _resultState, RectangleF _rect, string _displayTxt, Color _fillColor, bool _isFilled, int _fontSize)
{
ResultState = _resultState;
Rect = _rect;
DisplayTxt = _displayTxt;
FillColor = _fillColor;
IsFilled = _isFilled;
FontSize = _fontSize;
}
public override object Clone()
{
RectResultDisplay rect = new RectResultDisplay();
rect.ResultState = ResultState;
rect.Rect = Rect;
rect.DisplayTxt = DisplayTxt;
rect.FillColor = FillColor;
rect.FontSize = FontSize;
rect.IsFilled = IsFilled;
return rect;
}
public override void Draw(Graphics g)
{
g.DrawRectangle(new Pen(FillColor, 1), Rect.X, Rect.Y, Rect.Width, Rect.Height);
if (IsFilled)
{
g.FillRectangle(new SolidBrush(Color.FromArgb(20, FillColor)), Rect);
}
Font font = new Font("Tahoma", FontSize);
var txtSize = g.MeasureString(DisplayTxt, font);
g.DrawString(DisplayTxt, font, new SolidBrush(FillColor), (float)(Rect.X + Rect.Width / 2.0 - txtSize.Width / 2.0), Rect.Y + Rect.Height + 5);
}
public override string GetDisplayText()
{
return $"{ResultState} {DisplayTxt} ({Rect.X},{Rect.Y},{Rect.Width},{Rect.Height})";
}
public override bool IsIntersect(RectangleF rect)
{
return rect.IntersectsWith(Rect);
}
public override bool IsMouseHover(PointF p)
{
return false;
}
public override bool IsMouseInSide(PointF p)
{
return Rect.Contains(p);
}
public override void OnKeyDown(object sender, KeyEventArgs e)
{
}
public override void OnKeyUp(object sender, KeyEventArgs e)
{
}
public override void OnMouseDownWhenNew(PointF p)
{
}
public override void OnMouseMoveWhenNew(PointF p)
{
}
public override void OnMouseUpWhenNew(PointF p)
{
}
public override void Translate(float x, float y)
{
Rect.Offset(new PointF(x, y));
}
protected override void DrawResult(Graphics g)
{
}
}
}

109
DH.UI.Model.Winform/GridCtrl.Designer.cs generated Normal file
View File

@ -0,0 +1,109 @@
namespace XKRS.UI.Model.Winform
{
partial class GridCtrl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.chkShowGrid = new System.Windows.Forms.CheckBox();
this.tbGridValue = new System.Windows.Forms.TrackBar();
this.panel1 = new System.Windows.Forms.Panel();
this.colorDialog1 = new System.Windows.Forms.ColorDialog();
this.btnColor = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).BeginInit();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// chkShowGrid
//
this.chkShowGrid.Appearance = System.Windows.Forms.Appearance.Button;
// this.chkShowGrid.BackgroundImage = global::XKRS.UI.Model.Winform.Properties.Resources.grid;
this.chkShowGrid.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.chkShowGrid.Dock = System.Windows.Forms.DockStyle.Top;
this.chkShowGrid.Location = new System.Drawing.Point(0, 0);
this.chkShowGrid.Name = "chkShowGrid";
this.chkShowGrid.Size = new System.Drawing.Size(32, 30);
this.chkShowGrid.TabIndex = 0;
this.chkShowGrid.UseVisualStyleBackColor = true;
this.chkShowGrid.CheckedChanged += new System.EventHandler(this.chkShowGrid_CheckedChanged);
//
// tbGridValue
//
this.tbGridValue.AutoSize = false;
this.tbGridValue.Dock = System.Windows.Forms.DockStyle.Bottom;
this.tbGridValue.Location = new System.Drawing.Point(0, 21);
this.tbGridValue.Name = "tbGridValue";
this.tbGridValue.Orientation = System.Windows.Forms.Orientation.Vertical;
this.tbGridValue.Size = new System.Drawing.Size(32, 121);
this.tbGridValue.TabIndex = 1;
this.tbGridValue.TickStyle = System.Windows.Forms.TickStyle.Both;
this.tbGridValue.ValueChanged += new System.EventHandler(this.tbGridValue_ValueChanged);
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.Controls.Add(this.chkShowGrid);
this.panel1.Controls.Add(this.tbGridValue);
this.panel1.Location = new System.Drawing.Point(1, 1);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(32, 142);
this.panel1.TabIndex = 2;
//
// btnColor
//
this.btnColor.BackColor = System.Drawing.Color.Red;
this.btnColor.Location = new System.Drawing.Point(4, 150);
this.btnColor.Name = "btnColor";
this.btnColor.Size = new System.Drawing.Size(25, 23);
this.btnColor.TabIndex = 3;
this.btnColor.Text = " ";
this.btnColor.UseVisualStyleBackColor = false;
this.btnColor.Click += new System.EventHandler(this.btnColor_Click);
//
// GridCtrl
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
this.Controls.Add(this.btnColor);
this.Controls.Add(this.panel1);
this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134)));
this.Name = "GridCtrl";
this.Size = new System.Drawing.Size(32, 192);
((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).EndInit();
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.CheckBox chkShowGrid;
private System.Windows.Forms.TrackBar tbGridValue;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.ColorDialog colorDialog1;
private System.Windows.Forms.Button btnColor;
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace XKRS.UI.Model.Winform
{
public partial class GridCtrl : UserControl
{
public Action<bool> IsShowGridChanged { get; set; }
public Action<int> GridValueChanged { get; set; }
public Action<Color> GridColorChanged { get; set; }
public GridCtrl()
{
InitializeComponent();
IsChecked = chkShowGrid.Checked;
GridValue = tbGridValue.Value;
}
bool isChecked = false;
bool IsChecked
{
get => isChecked;
set
{
if (isChecked != value)
{
// IsShowGridChanged?.BeginInvoke(value, null, null);
Task.Run(() => IsShowGridChanged.Invoke(value));
}
isChecked = value;
}
}
int gridValue = 0;
int GridValue
{
get => gridValue;
set
{
if (gridValue != value)
{
// GridValueChanged?.BeginInvoke(value, null, null);
Task.Run(() => GridValueChanged.Invoke(value));
}
gridValue = value;
}
}
private void chkShowGrid_CheckedChanged(object sender, EventArgs e)
{
IsChecked = chkShowGrid.Checked;
}
private void tbGridValue_ValueChanged(object sender, EventArgs e)
{
GridValue = tbGridValue.Value;
}
private void btnColor_Click(object sender, EventArgs e)
{
if (colorDialog1.ShowDialog() == DialogResult.OK)
{
btnColor.BackColor = colorDialog1.Color;
// GridColorChanged?.BeginInvoke(btnColor.BackColor, null, null);
Task.Run(() => GridColorChanged.Invoke(btnColor.BackColor));
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,12 @@
using System.Windows.Forms;
namespace XKRS.UI.Model.Winform
{
public class GridCtrlHost : ToolStripControlHost
{
public GridCtrlHost(GridCtrl grid) : base(grid)
{
//Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, 134);
}
}
}

View File

@ -0,0 +1,78 @@
namespace XKRS.UI.Model.Winform
{
partial class IOIndicatorCtrl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
plStatus = new Panel();
lblDesc = new Label();
SuspendLayout();
//
// plStatus
//
plStatus.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left;
plStatus.Location = new Point(0, 0);
plStatus.Margin = new Padding(4);
plStatus.Name = "plStatus";
plStatus.Size = new Size(28, 34);
plStatus.TabIndex = 0;
plStatus.Paint += plStatus_Paint;
plStatus.DoubleClick += plStatus_DoubleClick;
//
// lblDesc
//
lblDesc.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
lblDesc.AutoSize = true;
lblDesc.Font = new Font("Tahoma", 11F, FontStyle.Regular, GraphicsUnit.World);
lblDesc.Location = new Point(36, 11);
lblDesc.Margin = new Padding(4, 0, 4, 0);
lblDesc.Name = "lblDesc";
lblDesc.Size = new Size(31, 13);
lblDesc.TabIndex = 1;
lblDesc.Text = "XXXX";
lblDesc.TextAlign = ContentAlignment.MiddleLeft;
lblDesc.DoubleClick += lblDesc_DoubleClick;
//
// IOIndicatorCtrl
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(lblDesc);
Controls.Add(plStatus);
Margin = new Padding(4);
Name = "IOIndicatorCtrl";
Size = new Size(138, 34);
ResumeLayout(false);
PerformLayout();
}
#endregion
private Panel plStatus;
private Label lblDesc;
}
}

View File

@ -0,0 +1,126 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace XKRS.UI.Model.Winform
{
public partial class IOIndicatorCtrl : UserControl
{
public IOIndicatorCtrl()
{
InitializeComponent();
}
private bool isON = false;
public bool IsOn
{
get => isON;
set
{
bool? temp = isON;
isON = value;
if (temp != isON)
{
RefreshStatus();
}
}
}
private void RefreshStatus()
{
if (InvokeRequired)
{
Invoke(new Action(() => RefreshStatus()));
}
else
{
plStatus.Invalidate();
}
}
private string desc = "";
public string Desc
{
get => desc;
set
{
desc = value;
DisplayDesc();
}
}
public int Index { get; set; }
private void DisplayDesc()
{
if (InvokeRequired)
{
Invoke(new Action(() => DisplayDesc()));
}
else
{
lblDesc.Text = Desc;
}
}
readonly PointF[] regionBlink = new PointF[]
{
new PointF(5,10),
new PointF(10,13),
new PointF(12,7),
new PointF(10,5)
};
public IOIndicatorCtrl(bool _isOn, string _desc, int index = 0)
{
InitializeComponent();
IsOn = _isOn;
Desc = _desc;
Index = index;
}
/// <summary>
/// 更新绘制图标
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void plStatus_Paint(object sender, PaintEventArgs e)
{
Panel pl = sender as Panel;
Graphics g = e.Graphics;
g.Clear(SystemColors.Control);
if (IsOn)
{
g.FillEllipse(Brushes.LightGreen, pl.ClientRectangle);
}
else
{
g.FillEllipse(Brushes.Gray, pl.ClientRectangle);
}
g.FillPolygon(Brushes.White, regionBlink);
}
public event Action<string, bool, int> OnIODoubleClick;
private void lblDesc_DoubleClick(object sender, EventArgs e)
{
OnIODoubleClick?.Invoke(Name, IsOn, Index);
}
private void plStatus_DoubleClick(object sender, EventArgs e)
{
OnIODoubleClick?.Invoke(Name, IsOn, Index);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>