主頁 > .NET開發 > (七十七)c#Winform自定義控制元件-采樣控制元件-HZHControls

(七十七)c#Winform自定義控制元件-采樣控制元件-HZHControls

2020-09-11 08:22:55 .NET開發

官網

http://www.hzhcontrols.com

前提

入行已經7,8年了,一直想做一套漂亮點的自定義控制元件,于是就有了本系列文章,

GitHub:https://github.com/kwwwvagaa/NetWinformControl

碼云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果覺得寫的還行,請點個 star 支持一下吧

歡迎前來交流探討: 企鵝群568015492 企鵝群568015492

來都來了,點個【推薦】再走吧,謝謝

NuGet

Install-Package HZH_Controls

目錄

https://www.cnblogs.com/bfyx/p/11364884.html

用處及效果

注意觀察各個控制元件交疊的地方,是不是發現他們沒有遮擋?這就是這個控制元件的妙處了,

準備作業

先說明一下這個控制元件的作用,很多時候我們需要一個圖片型別的控制元件,但是有需要密集的放在一起,如果單純的設定背景圖或image的話  交疊在一起的部分就會存在遮擋現象,所有就有了這個控制元件,

該控制元件可以根據設定的采樣圖片來裁剪有用的繪圖區域,這樣的好處就是在交疊的時候,無用區域不會遮擋,

這個用GDI+畫的,另外也用到了一點三角函式,不明白的話 可以先百度下

開始

添加一個類UCSampling ,繼承UserControl

添加屬性

 1   /// <summary> 2         /// The sampling imag 3         /// </summary> 4         private Bitmap samplingImag = null; 5         /// <summary> 6         /// Gets or sets the sampling imag. 7         /// </summary> 8         /// <value>The sampling imag.</value> 9         [Browsable(true), Category("自定義屬性"), Description("采樣圖片"), Localizable(true)]10         public Bitmap SamplingImag11         {12             get { return samplingImag; }13             set14             {15                 samplingImag = value;16                 ResetBorderPath();17                 Invalidate();18             }19         }20 21         /// <summary>22         /// The transparent23         /// </summary>24         private Color? transparent = null;25 26         /// <summary>27         /// Gets or sets the transparent.28         /// </summary>29         /// <value>The transparent.</value>30         [Browsable(true), Category("自定義屬性"), Description("透明色,如果為空,則使用0,0坐標處的顏色"), Localizable(true)]31         public Color? Transparent32         {33             get { return transparent; }34             set35             {36                 transparent = value;37                 ResetBorderPath();38                 Invalidate();39             }40         }41 42         /// <summary>43         /// The alpha44         /// </summary>45         private int alpha = 50;46 47         /// <summary>48         /// Gets or sets the alpha.49         /// </summary>50         /// <value>The alpha.</value>51         [Browsable(true), Category("自定義屬性"), Description("當作透明色的透明度,小于此透明度的顏色將被認定為透明,0-255"), Localizable(true)]52         public int Alpha53         {54             get { return alpha; }55             set56             {57                 if (value < 0 || value > 255)58                     return;59                 alpha = value;60                 ResetBorderPath();61                 Invalidate();62             }63         }64 65         /// <summary>66         /// The color threshold67         /// </summary>68         private int colorThreshold = 10;69 70         /// <summary>71         /// Gets or sets the color threshold.72         /// </summary>73         /// <value>The color threshold.</value>74         [Browsable(true), Category("自定義屬性"), Description("透明色顏色閥值"), Localizable(true)]75         public int ColorThreshold76         {77             get { return colorThreshold; }78             set79             {80                 colorThreshold = value;81                 ResetBorderPath();82                 Invalidate();83             }84         }85 86         /// <summary>87         /// The bit cache88         /// </summary>89         private Bitmap _bitCache;

在大小改變或圖片改變時重新計算邊界

 1  /// <summary> 2         /// The m border path 3         /// </summary> 4         GraphicsPath m_borderPath = new GraphicsPath(); 5  6         /// <summary> 7         /// Handles the SizeChanged event of the UCSampling control. 8         /// </summary> 9         /// <param name="sender">The source of the event.</param>10         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>11         void UCSampling_SizeChanged(object sender, EventArgs e)12         {13             ResetBorderPath();14         }15 16         /// <summary>17         /// Resets the border path.18         /// </summary>19         private void ResetBorderPath()20         {21             if (samplingImag == null)22             {23                 m_borderPath = this.ClientRectangle.CreateRoundedRectanglePath(5);24             }25             else26             {27                 var bit = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);28                 using (var bitg = Graphics.FromImage(bit))29                 {30                     bitg.DrawImage(samplingImag, this.ClientRectangle, 0, 0, samplingImag.Width, samplingImag.Height, GraphicsUnit.Pixel);31                 }32                 _bitCache = bit;33                 m_borderPath = new GraphicsPath();34                 List<PointF> lstPoints = GetBorderPoints(bit, transparent ?? samplingImag.GetPixel(0, 0));35                 m_borderPath.AddLines(lstPoints.ToArray());36                 m_borderPath.CloseAllFigures();37             }38         }39 40         /// <summary>41         /// Gets the border points.42         /// </summary>43         /// <param name="bit">The bit.</param>44         /// <param name="transparent">The transparent.</param>45         /// <returns>List&lt;PointF&gt;.</returns>46         private List<PointF> GetBorderPoints(Bitmap bit, Color transparent)47         {48             float diameter = (float)Math.Sqrt(bit.Width * bit.Width + bit.Height * bit.Height);49             int intSplit = 0;50             intSplit = (int)(7 - (diameter - 200) / 100);51             if (intSplit < 1)52                 intSplit = 1;53             List<PointF> lstPoint = new List<PointF>();54             for (int i = 0; i < 360; i += intSplit)55             {56                 for (int j = (int)diameter / 2; j > 5; j--)57                 {58                     Point p = GetPointByAngle(i, j, new PointF(bit.Width / 2, bit.Height / 2));59                     if (p.X < 0 || p.Y < 0 || p.X >= bit.Width || p.Y >= bit.Height)60                         continue;61                     Color _color = bit.GetPixel(p.X, p.Y);62                     if (!(((int)_color.A) <= alpha || IsLikeColor(_color, transparent)))63                     {64                         if (!lstPoint.Contains(p))65                         {66                             lstPoint.Add(p);67                         }68                         break;69                     }70                 }71             }72             return lstPoint;73         }74 75         /// <summary>76         /// Determines whether [is like color] [the specified color1].77         /// </summary>78         /// <param name="color1">The color1.</param>79         /// <param name="color2">The color2.</param>80         /// <returns><c>true</c> if [is like color] [the specified color1]; otherwise, <c>false</c>.</returns>81         private bool IsLikeColor(Color color1, Color color2)82         {83             var cv = Math.Sqrt(Math.Pow((color1.R - color2.R), 2) + Math.Pow((color1.G - color2.G), 2) + Math.Pow((color1.B - color2.B), 2));84             if (cv <= colorThreshold)85                 return true;86             else87                 return false;88         }
 1  #region 根據角度得到坐標    English:Get coordinates from angles 2         /// <summary> 3         /// 功能描述:根據角度得到坐標    English:Get coordinates from angles 4         /// 作  者:HZH 5         /// 創建日期:2019-09-28 11:56:25 6         /// 任務編號:POS 7         /// </summary> 8         /// <param name="angle">angle</param> 9         /// <param name="radius">radius</param>10         /// <param name="origin">origin</param>11         /// <returns>回傳值</returns>12         private Point GetPointByAngle(float angle, float radius, PointF origin)13         {14             float y = origin.Y + (float)Math.Sin(Math.PI * (angle / 180.00F)) * radius;15             float x = origin.X + (float)Math.Cos(Math.PI * (angle / 180.00F)) * radius;16             return new Point((int)x, (int)y);17         }18         #endregion

取邊界的思路如下:

1,以控制元件中心為原點,按照一定的角度順時針依次進行旋轉,

2、每次旋轉后,按照此角度從外向內,找到第一個不是透明的點記錄下來,這就是外邊界點

這個取邊界演算法感覺并不是太好,如果哪位小伙伴有更好的演算法,希望可以探討一下

重繪

 1   protected override void OnPaint(PaintEventArgs e) 2         { 3             base.OnPaint(e); 4             e.Graphics.SetGDIHigh(); 5  6             this.Region = new System.Drawing.Region(m_borderPath); 7             8             if (_bitCache != null) 9                 e.Graphics.DrawImage(_bitCache, 0, 0);10            11         }

 

最后的話

如果你喜歡的話,請到 https://gitee.com/kwwwvagaa/net_winform_custom_control 點個星星吧

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/4899.html

標籤:WinForm

上一篇:(七十六)c#Winform自定義控制元件-表單驗證組件-HZHControls

下一篇:(七十八)c#Winform自定義控制元件-倒影組件-HZHControls

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more