星期四, 12月 31, 2020

[C#] GraphicsPath.AddArc() Angle 參數

參考 GraphicsPath.AddArc 方法 內範例來了解 StartAngle 和 SweepAngle 這兩個參數的意義和使用

參數說明

類型說明
StartAngleThe starting angle of the arc, measured in degrees clockwise from the x-axis..
SweepAngleThe angle between startAngle and the end of the arc.

C# Code,稍微修正文章內範例
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace GraphicsSample
{
    public partial class FrmArcAngle : Form
    {
        public FrmArcAngle()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            ArcAngle(e);
            base.OnPaint(e);
        }

        private void ArcAngle(PaintEventArgs e)
        {
            // 設定一個正方形
            Rectangle rect = new Rectangle(130, 20, 100, 100);

            // 透過 GraphicsPath 來畫橢圓弧形
            GraphicsPath myPath = new GraphicsPath();
            myPath.StartFigure();
            // X 軸角度為 0 並從 X 軸為 0 度開始畫一個 180 度橢圓弧形
            myPath.AddArc(rect, 0, 180);
            // 把起點和終點連起來
            myPath.CloseFigure();

            // 進行繪製
            e.Graphics.DrawRectangle(Pens.Black, rect);
            e.Graphics.DrawPath(new Pen(Color.Red, 5), myPath);
        }
    }
}
[C#] GraphicsPath.AddArc() Angle 參數

星期二, 12月 29, 2020

[C#] TreeView 圖示

根據 
的筆記

把 ImageList 所需三張圖片,放在 Resource 內來使用


using System;
using System.Drawing;
using System.Windows.Forms;
using TreeViewImage.Properties;

namespace TreeViewImage
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        ImageList imageList4TreeView = new ImageList();

        private void Form1_Load(object sender, EventArgs e)
        {
            myTreeView.Font = new Font("微軟正黑體", 16F);

            // 建立搭配 TreeView 使用的 ImageList 圖庫
            imageList4TreeView.ImageSize = new Size(36, 36);
            imageList4TreeView.Images.Add(Resources.Community);
            imageList4TreeView.Images.Add(Resources.Man);
            imageList4TreeView.Images.Add(Resources.Woman);

            // 設定 TreeView 使用 ImageList
            myTreeView.ImageList = imageList4TreeView;

            DrawTreeView();
        }

        /// <summary>
        /// 在 TreeNode 內指定 ImageIndex 和 SelectedImageIndex 來顯示圖片
        /// </summary>
        private void DrawTreeView()
        {
            TreeNode root = new TreeNode() { Text = "組織圖" , ImageIndex = 0 };
            myTreeView.Nodes.Add(root);

            TreeNode DepartmentNode;
            TreeNode EmployeeNode;
            int index;
            for (int i = 1; i <= 2; i++)
            {
                DepartmentNode = new TreeNode() { Text = $"部門-{i}", ImageIndex = 0 , SelectedImageIndex = 0};
                root.Nodes.Add(DepartmentNode);

                for (int j = 1; j <= 4; j++)
                {
                    index = j % 2 == 0 ? 1 : 2;
                    EmployeeNode = new TreeNode() { Text = $"員工-{j}", ImageIndex = index , SelectedImageIndex = index };
                    DepartmentNode.Nodes.Add(EmployeeNode);
                }
            }

            myTreeView.ExpandAll();
        }
    }
}


SelectedImageIndex 說明
Gets or sets the image list index value of the image that is displayed when the tree node is in the selected state.
因為刻意變化每個 TreeNode 圖示,導致點選 TreeNode 後會根據 TreeView.SelectedImageIndex 來變化圖示,原是想說把 TreeView.SelectedImageIndex = -1 來取消,但沒有作用,最後是在建立 TreeNode 時會一併設定 TreeNode.SelectedImageIndex,避免受 TreeView.SelectedImageIndex 影響

ImageKey 和 ImageIndex 說明
ImageKey 和 ImageIndex 屬性互斥
  • 設定 ImageKey,ImageIndex 會自動設為 -1
  • 設定 ImageIndex,ImageKey 會自動設為空字串 ( "" ) 

星期日, 12月 27, 2020

[VFP] CTOD() 日期轉換

公司內發生的 bug,因為變成 SET DATE 環境日期設定,從 Taiwan 改為 YMD,導致 CTOD() 轉換日期異常,導致一連串錯誤,用段 Code 來記錄該情況
lcMonth = "10912"
lcYY = SUBSTR(lcMonth,1,3)
lcMM = SUBSTR(lcMonth,4,2)

SET DATE YMD
ldYMDDate = CTOD(lcYY + "/" + lcMM + "/01")
ldYMDYear = YEAR(ldYMDDate)

SET DATE TAIWAN
ldTAIWANDDate = CTOD(lcYY + "/" + lcMM + "/01")
ldTAIWANDYear = YEAR(ldTAIWANDDate)

TEXT TO lcMessage TEXTMERGE NOSHOW PRETEXT 2
	SET DATE YMD
	CTOD 轉日期:<<ldYMDDate>>
	取出西元年:<<ldYMDYear>>
	
	SET DATE TAIWAN
	CTOD 轉日期:<<ldTAIWANDDate>>
	取出西元年:<<ldTAIWANDYear>>
ENDTEXT 
MESSAGEBOX(lcMessage , 0 + 64 , "測試結果")
從下圖就可以發現,YMD 變成西元 109 年,Taiwan 則是西元 2020 年

[VFP] CTOD() 日期轉換-1

因為 CTOD() 會受 SET DATE 影響,所以建立一律改為用 DATE() 來轉日期,避免困惱

星期六, 12月 26, 2020

[C#] 繪製文字 - 對齊

根據 作法:對齊繪製的文字 的練習筆記
using System;
using System.Drawing;
using System.Windows.Forms;

namespace GraphicsSample
{
    public partial class FrmText : Form
    {

        public FrmText()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            DrawStringAlignment(e);
            RenderTextCenter(e);
        }

        Font fontAlignment = new Font("微軟正黑體", 12, FontStyle.Bold);
        Pen penRect = Pens.Black;

        private void DrawStringAlignment(PaintEventArgs e)
        {
            string text = "Use StringFormat and Rectangle objects to center text in a rectangle.";
            Rectangle rect = new Rectangle(10, 10, 130, 140);

            // Alignment:水平對齊
            // LineAlignment:垂直對齊
            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Center;
            stringFormat.LineAlignment = StringAlignment.Center;

            // 在矩形內繪製文字
            e.Graphics.DrawString(text, fontAlignment, Brushes.Blue, rect, stringFormat);
            e.Graphics.DrawRectangle(penRect, rect);
        }

        private void RenderTextCenter(PaintEventArgs e)
        {
            string text = "Use TextFormatFlags and Rectangle objects to center text in a rectangle.";
            Rectangle rect = new Rectangle(150, 10, 130, 140);

            // HorizontalCenter:水平置中
            // VerticalCenter:垂直置中
            // WordBreak:在字的結尾讓文字分行
            TextFormatFlags flags = TextFormatFlags.HorizontalCenter |
                TextFormatFlags.VerticalCenter |
                TextFormatFlags.WordBreak;

            // 在矩形內繪製文字
            TextRenderer.DrawText(e.Graphics, text, fontAlignment, rect, Color.Blue, flags);
            e.Graphics.DrawRectangle(penRect, rect);
        } 
    }
}

星期五, 12月 25, 2020

[C#] 繪製文字

繪製文字有兩種方法
  1. Graphics.DrawString:作法:在 Windows Form 上繪製文字
  2. TextRenderer.DrawText:作法:使用 GDI 繪製文字
該篇是上述兩篇筆記
using System;
using System.Drawing;
using System.Windows.Forms;

namespace GraphicsSample
{
    public partial class FrmText : Form
    {
        private Font font = new Font("微軟正黑體" , 30);

        public FrmText()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            DrawString();
            RenderText(e);
        }
        public void DrawString()
        {
            using (Graphics g = this.CreateGraphics())
            using (SolidBrush b = new SolidBrush(Color.Black))
            {
                string drawString = "Graphics.DrawString:Sample Text";
                float x = 10.0F;
                float y = 10.0F;
                g.DrawString(drawString, font, b, x, y);
            }
        }

        private void RenderText(PaintEventArgs e)
        {
            // TextFormatFlags 列舉說明
            // Bottom:文字對齊底部
            // EndEllipsis:移除已修剪字行的結尾,並以省略符號取代
            TextFormatFlags flags = TextFormatFlags.Bottom | TextFormatFlags.EndEllipsis;
            TextRenderer.DrawText(e.Graphics, "TextRenderer.DrawText:Sample Text", font,
                new Rectangle(10, 40, 700, 100), SystemColors.ControlText, flags);
        }
    }
}
文章重點
The DrawText methods of the TextRenderer class are not supported for printing. When printing, always use the DrawString methods of the Graphics class.

星期四, 12月 24, 2020

[C#] 繪製實心矩形

根據 作法:在 Windows Form 上繪製實心矩形 的筆記
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void DrawRectangle()
        {
            using (Graphics g = this.CreateGraphics())
            using (Pen p = new Pen(Color.Black))
            using (SolidBrush b = new SolidBrush(Color.LightBlue))
            {
                Rectangle rec = new Rectangle(20, 20, 300, 300);

                p.Width = 10;
                p.DashStyle = DashStyle.Solid;
                g.DrawRectangle(p, rec);

                g.FillRectangle(b, rec);
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            DrawRectangle();
        }
    }
}
 文章內注意事項
You should always call Dispose on any objects that consume system resources, such as Brush and Graphics objects. 
繪製過程假如沒有特別需求,EX:Pen 需要指定寬度 (Width)、線條樣式 (DashStyle) 等需求,.NET Framework 有提供 BrushesPens 靜態類別可以直接指定顏色

星期一, 12月 21, 2020

[C#] 利用 XSD 驗證 XML

根據 使用 XmlSchemaSet 進行 XML 架構 (XSD) 驗證如何使用 XSD 驗證 的測試筆記,該文章內容是以判斷 name、last-name 和 first-name 的 sequence 是否有效

XSD,文章內容有用到功能,從 XML Schema Tutorial 內抓出來整理

類型說明
sequenceThe sequence element specifies that the child elements must appear in a sequence.
Each child element can occur from 0 to any number of times.
minOccursThe minOccurs indicator specifies the minimum number of times an element can occur.
default value 1
maxOccursThe maxOccurs indicator specifies the maximum number of times an element can occur.
useAttributes are optional by default. To specify that the attribute is required, use the "use" attribute
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="bookstore">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="book">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="title" type="xs:string" />
              <xs:element name="author">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element minOccurs="0" name="name" type="xs:string" />
                    <xs:element minOccurs="0" name="last-name" type="xs:string" />
                    <xs:element minOccurs="0" name="first-name" type="xs:string" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element name="price" type="xs:decimal" />
            </xs:sequence>
            <xs:attribute name="genre" type="xs:string" use="required" />
            <xs:attribute name="publicationdate" type="xs:date" use="required" />
            <xs:attribute name="ISBN" type="xs:string" use="required" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

星期六, 12月 19, 2020

[C#] csv 檔案轉換為 XML

根據官方該篇 - 如何從 CSV 檔案產生 XML (LINQ to XML) 的練習
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;

namespace XMLConvert
{
    class Program
    {
        static void Main(string[] args)
        {
            string csvFileFullName = @"D:\Demo\CSV2XML.csv";

            CSVFileCreate(csvFileFullName);

            List<string> source = CSVReader(csvFileFullName);

            XDocument xDoc = new XDocument
            (
                new XDeclaration("1.0", "utf-8", "yes"),
                new XComment("Linq2XML"),
                new XElement
                (
                    "Root",
                    source.Select(s => s.Split(','))
                        .Select
                        (e =>
                            new XElement("Customer", new XAttribute("CustomerID", e[0]),
                                new XElement("CompanyName", e[1]),
                                new XElement("ContactName", e[2]),
                                new XElement("ContactTitle", e[3]),
                                new XElement("Phone", e[4]),
                                new XElement("FullAddress",
                                    new XElement("Address", e[5]),
                                    new XElement("City", e[6]),
                                    new XElement("Region", e[7]),
                                    new XElement("PostalCode", e[8]),
                                    new XElement("Country", e[9]))))
                        )
            );

            xDoc.Save(@"D:\Demo\CSV2XML.xml");
        }

        private static void CSVFileCreate(string csvFileFullName)
        {
            string csvString = @"GREAL,Great Lakes Food Market,Howard Snyder,Marketing Manager,(503) 555-7555,2732 Baker Blvd.,Eugene,OR,97403,USA
HUNGC,Hungry Coyote Import Store,Yoshi Latimer,Sales Representative,(503) 555-6874,City Center Plaza 516 Main St.,Elgin,OR,97827,USA
LAZYK,Lazy K Kountry Store,John Steel,Marketing Manager,(509) 555-7969,12 Orchestra Terrace,Walla Walla,WA,99362,USA
LETSS,Let's Stop N Shop,Jaime Yorres,Owner,(415) 555-5938,87 Polk St. Suite 5,San Francisco,CA,94117,USA";

            File.WriteAllText(csvFileFullName, csvString);
        }

        private static List<string> CSVReader(string csvFileFullName)
        {
            return File.ReadAllLines(csvFileFullName).ToList();
        }
    }
}

結果截圖只顯示一筆資料而已

[C#] csv 檔案轉換為 XML

星期三, 12月 16, 2020

[VS] 重設視窗配置

最近使用 VS 時,發生原本釘在下方的 [錯誤清單]、[工作清單] 等視窗,每次開啟 VS 都會消失,今天莫名其妙的 [Team Explorer] 竟然叫不出來,最後都是透過 [重設視窗配置] 來解決該問題

  [VS] 重設視窗配置