同事認定正常情況,輸出後內容頁朝上
星期二, 7月 27, 2021
星期六, 7月 24, 2021
[C#] ContextMenuStrip
根據該篇 ContextMenuStrip 類別 的練習,以 MenuStrip + ContextMenuStrip 為主,不會紀錄 ToolStrip 使用方式,該官方範例會說明 ContextMenuStrip 使用方式,並把 ContextMenuStrip 綁上 MenuStrip 使用
點選 MenuStrip
使用 ContextMenuStrip
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace ContextMenuStripSample
{
public partial class Form1 : Form
{
private ContextMenuStrip fruitContextMenuStrip;
public Form1()
{
InitializeComponent();
fruitContextMenuStrip = new ContextMenuStrip();
fruitContextMenuStrip.Opening += FruitContextMenuStrip_Opening;
this.ContextMenuStrip = fruitContextMenuStrip;
ButtonInit();
MenuStripInit();
}
private void ButtonInit()
{
Button b = new Button();
b.Location = new Point(60, 60);
this.Controls.Add(b);
b.ContextMenuStrip = fruitContextMenuStrip;
}
private void MenuStripInit()
{
MenuStrip ms = new MenuStrip();
ToolStripMenuItem fruitToolStripMenuItem = new ToolStripMenuItem("Fruit", null, null, "Fruit");
ms.Items.Add(fruitToolStripMenuItem);
ms.Dock = DockStyle.Top;
// MenuStrip.Fruit 選項透過 ContextMenuStrip 來顯示
fruitToolStripMenuItem.DropDown = fruitContextMenuStrip;
this.Controls.Add(ms);
}
private void FruitContextMenuStrip_Opening(object sender, CancelEventArgs e)
{
Control ctl = fruitContextMenuStrip.SourceControl as Control;
// 判斷 ToolStripDropDownItem 會包含 ToolStripMenuItem
ToolStripDropDownItem tsi = fruitContextMenuStrip.OwnerItem as ToolStripDropDownItem;
fruitContextMenuStrip.Items.Clear();
// Check the source control first.
if (ctl != null)
{
fruitContextMenuStrip.Items.Add("右鍵使用 ContextMenuStrip");
fruitContextMenuStrip.Items.Add("Source:" + ctl.GetType().ToString());
}
else if (tsi != null)
{
// Add custom item (ToolStripDropDownButton or ToolStripMenuItem)
fruitContextMenuStrip.Items.Add("點選 MenuStrip");
fruitContextMenuStrip.Items.Add("Source:" + tsi.GetType().ToString());
}
// 原來分隔線可以直接用文字 - 代表
fruitContextMenuStrip.Items.Add("-");
fruitContextMenuStrip.Items.Add(new ToolStripSeparator());
ToolStripMenuItem CustomeItem = new ToolStripMenuItem();
CustomeItem.Click += Item_Click;
fruitContextMenuStrip.Items.Add("Custom", null, Item_Click);
fruitContextMenuStrip.Items.Add("Apples" , null , Item_Click);
fruitContextMenuStrip.Items.Add("Oranges" , null , Item_Click);
fruitContextMenuStrip.Items.Add("Pears" , null , Item_Click);
// Set Cancel to false. It is optimized to true based on empty entry.
// e.Cancel = true 的話,MenuStrip 的 ContextMenuStrip 就不會顯示啦
e.Cancel = false;
}
private void Item_Click(object sender, EventArgs e)
{
MessageBox.Show((sender as ToolStripMenuItem).Text);
}
}
}
以前都是每一個 ToolStripMenuItem 都要單獨產生後去綁定 Click 事件,該練習時才發現說,有一個多載方法可以直接傳進去,小發現
星期五, 7月 23, 2021
[C#] 繪製-多邊形
公司內有使用到 FillPolygon 來繪製圖型,拿官方範例 - Graphics.FillPolygon 方法 來了解
C# Code
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace GraphicsSample
{
public partial class FrmFillPolygon : Form
{
public FrmFillPolygon()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
FillPolygonWinding(e);
}
public void FillPolygonWinding(PaintEventArgs e)
{
PointF point1 = new PointF(50.0F, 50.0F);
PointF point2 = new PointF(100.0F, 25.0F);
PointF point3 = new PointF(200.0F, 5.0F);
PointF point4 = new PointF(250.0F, 50.0F);
PointF point5 = new PointF(300.0F, 100.0F);
PointF point6 = new PointF(350.0F, 200.0F);
PointF point7 = new PointF(250.0F, 250.0F);
PointF[] curvePoints = { point1, point2, point3, point4, point5, point6, point7 };
FillMode fillMode = FillMode.Winding;
e.Graphics.FillPolygon(Brushes.LightBlue, curvePoints, fillMode);
}
}
}
範例筆記- [250,50] 和 [300,100] 個人感覺剛好形成一條直線,導致 [250,50] 沒有很明顯
- 該範例設定 FillMode 其實看不出效果
- 參考資料
- FillMode 列舉
星期二, 7月 20, 2021
[EF] edmx 實體容器名稱
發生需要重建 edmx 的情況,但重建後一直無法使用該 DbContext,查才發現引用是看 [實體容器名稱] 屬性名稱,而不是 edmx 檔案名稱,但該 DbContext 是 Entity
星期一, 7月 19, 2021
[EF] Schema specified is not valid. - 資料型態不一致
在 edmx 上把 model property 改為自訂 enum 後執行,發生下列錯誤訊息
System.Data.Entity.Core.MetadataException: Schema specified is not valid. Errors: No corresponding object layer type could be found for the conceptual type 'Namespace.EnumName'. The following information may be useful in resolving the previous error: The underlying type of CLR enumeration type does not match the underlying type of EDM enumeration type.
檢查 Table 欄位資料型態 和 自訂 enum 發現
- Table 欄位資料形態為 tinyint
- 自訂 enum 並沒有特別宣告繼承型別,預設為 int
兩者資料型別對應不一致,把自訂 enum 明確宣告繼承至 byte 就解決該問題
星期四, 7月 15, 2021
星期五, 7月 09, 2021
[C#] 透過 ToolStripControlHost 自訂 ToolStripItem
根據 作法:使用 ToolStripControlHost 包裝 Windows Forms 控制項 的筆記,該篇是把 MonthCalendar 標準控件塞進 ToolStripItem 內,有註冊公開的 DateChanged 事件來把結果傳回 TextBox 上,效果如下圖
建構子是最重要部分,因為要把 MonthCalendar 傳給 ToolStripControlHost
在 Form 內把自訂的 ToolStripMonthCalendar 塞進 MenuStrip 上使用,MenuStrip 和 ToolStripMenuItem 是直接拖曳建立上 Form 的using System;
using System.Windows.Forms;
namespace UCToolStripControlHost
{
public class ToolStripMonthCalendar : ToolStripControlHost
{
// 把 MonthCalendar 傳進 ToolStripControlHost 建構子
public ToolStripMonthCalendar() : base(new MonthCalendar())
{
}
public MonthCalendar MonthCalendarControl
{
get
{
return Control as MonthCalendar;
}
}
// 公開 FirstDayOfWeek 屬性
public Day FirstDayOfWeek
{
get
{
return MonthCalendarControl.FirstDayOfWeek;
}
set
{
MonthCalendarControl.FirstDayOfWeek = value;
}
}
// 公開 AddBoldedDate 方法
public void AddBoldedDate(DateTime dateToBold)
{
MonthCalendarControl.AddBoldedDate(dateToBold);
}
// 公開 DateChanged 事件
public event DateRangeEventHandler DateChanged
{
add { MonthCalendarControl.DateChanged += value; }
remove { MonthCalendarControl.DateChanged -= value; }
}
}
}
using System;
using System.Windows.Forms;
namespace UCToolStripControlHost
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ToolStripMonthCalendar monthCalendar = new ToolStripMonthCalendar();
toolStripMenuItem1.DropDownItems.Add(monthCalendar);
monthCalendar.DateChanged += (sender, e) =>
{
txtStartDate.Text = e.Start.ToString();
};
}
}
}
- 參考資料
- 自訂ToolStrip的ToolStripItem - 自訂控件
- C# 自定义承载控件 - DateTimePicker
星期三, 7月 07, 2021
[C#] 控件智能標籤 - 設定屬性值
在 [C#] 控件智能標籤 內有筆記該重點 - 更新要透過 PropertyDescriptor 來完成
查 Code 才發現,原來使用方式是透過 Type.GetProperty().SetValue() 來設定屬性值,而不是透過 PropertyDescriptor
簡易紀錄
When a property or method in the class derived from DesignerActionList changes the state of the associated control, these changes should not be made by direct setter calls to the component's properties. Instead, such changes should be made through an appropriately created PropertyDescriptor. This indirect approach ensures that smart-tag undo and UI update actions function correctly.從下圖可以看出,在智能標籤上把 Name 修改為 ChangeName 後,屬性視窗內的 Name 還是 flatButton1,沒有跟著變化
簡易紀錄
// 異常方式
Type.GetProperty().SetValue();
// 正確方式
TypeDescriptor.GetProperties().SetValue();
星期一, 7月 05, 2021
星期六, 7月 03, 2021
[EF] The entity type is not part of the model for the current context
新增 DContext 時搞烏龍,連線字串內指定 emdx 的 metadata 沒有指定到對的 DbContext,導致執行時就拋出該錯誤訊息
修正連線字串 edmx metadata 的 csdl、ssdl 和 msl 對應 DbContext 就解決該問題
The entity type Type is not part of the model for the current context
修正連線字串 edmx metadata 的 csdl、ssdl 和 msl 對應 DbContext 就解決該問題
<connectionStrings>
<add name="CustomDbContext"
connectionString="
metadata=
res://*/DbContext.CustomDbContext.csdl|
res://*/DbContext.CustomDbContext.ssdl|
res://*/DbContext.CustomeDbContext.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=.\SQLInstance;
initial catalog=DBName;
User Id=UserID;
Password=PWD;
integrated security=False;
multipleactiveresultsets=True;
application name=EntityFramework""
providerName="System.Data.EntityClient"/>
</connectionStrings>