主頁 > .NET開發 > [C#] (原創)一步一步教你自定義控制元件——01,TrackBar

[C#] (原創)一步一步教你自定義控制元件——01,TrackBar

2020-09-09 23:50:11 .NET開發

一、前言

技術沒有先進落后之分,只有合不合適,

WinForm有著非常多的優點,在使用WinForm久了之后,難免會覺得WinForm自帶的某些控制元件外觀上有些許樸素、或者功能上有些不如意,自然而然便想去美化這些控制元件,或者給控制元件添加一些額外功能,而這便是自定義控制元件的意義所在,

自定義控制元件的難度并不大,但是卻處在一個比較尷尬的位置:

1,一般的教材不會講——因為還是有難度的,而且一般用不上;

2,而網上或書上所找到的自定義控制元件相關知識教程里,大多都是給一個已完成的自定義控制元件,再附上原始碼,只有了了注釋和說明,畢竟難度不大,懂的自然懂,而且對懂的人來說,看別人的自定義控制元件往往是為了看一下實作的思路或某個點的實作方法,因為很多都是一點就透,

對于初學者而言,要想掌握自定義控制元件,就需要花費不少的時間去學習那些源代碼、去模仿、去練習、去摸索,最后一步步去歸納總結出適合自己的一條路,當掌握了之后,回頭看去,會發現其實真的不難,耗費的時間與學習的難度并不成正比,這些額外的時間就花費在了摸索和總結上了,

我也是這樣一步步走來的,所以不想讓大家再花費這么多的時間去掌握一項并不太難的知識,便有了這篇文章,

在本文中,我會從零開始,帶著大家一步一步去實作一個自定義控制元件,同時會分享一些我的經驗之談,相信看完的你,一定會有所識訓,

本篇的自定義控制元件是:TrackBar

本文地址:https://www.cnblogs.com/lesliexin/p/13265707.html


 

二、前期分析

(一)為什么需要去自定義控制元件?

我們來分析一下為什么要去自定義控制元件,

以本文要實作的TrackBar為例,最主要的原因便 是系統自帶的TrackBar太過樸素,所以需要一款比較好看的TrackBar控制元件,

系統自帶的TrackBar:

預想的TrackBar樣式:

(二)實作目標

在實作一個自定義控制元件前,我們要確定一下我們要實作的目標,比如外觀、功能、特點等,

1,外觀

個人經驗之談

在設計預想樣式時,可以何用任何方式,只要自己可以看明白就行,但是還是推薦使用繪圖軟體去做一個示意圖,主要是因為在自定義控制元件時,往往會需要用到一些坐標、寬、高等值,特別是和GDI+有關時,使用繪圖軟體則可以去準確和清晰的標注出來這些資訊,并進行相關的計算,

我想實作的TrackBar的外觀樣式如下:

2,功能

參考系統的TrackBar,可以將所需要的功能歸為下面幾點:

(1)支持滑鼠點擊,

(2)支持滑鼠拖動,

(3)支持修改顏色, 

3,特點

既然全實作自己的TrackBar,肯定要有自己的特點,

(1)支持顏色調整,包括背景色和前景色,

(2)支持圓角顯示,和直角顯示,

(三)技術分析

在自定義控制元件的目標定好之后,接下來便是分析實作上述目標所需要的技術,

1,整體實作

 自定義的TrackBar從邏輯上可以分為兩層:背景條(Bar)和滑塊(Slider),

在具體實作時也是按照這兩層的思路去分層實作,

2,主要技術

通過上面的分析的示意,我們發現GDI+可以實作上述目標,所以我們的主要技術便是——GDI+,

3,圓角和直角的實作

直角可以使用GDI+中的Graphics.DrawLine去實作,那么圓角怎么實作呢?

其實也很簡單,仍然使用Graphics.DrawLine實作,不過在創建Pen時,需要設定一下LineCap,通過LineCap可以實作多種樣式,除了圓角外,還有菱形、箭頭等等,

具體的設定后文會講解,此處不再贅述,

MSDN中關于LineCap的說明如下:

指定可用線帽樣式,Pen 物件以該線帽結束一段直線,

 


 

三、開始實作

(一)前期準備

1,創建自定義控制元件類別庫專案

個人經驗之談

建議創建自定義控制元件時,將自定義控制元件寫在一個單獨的類別庫里,主要的目的是提高復用性,同時也方便管理,以及方便控制元件間的相互呼叫,

關于控制元件間的相互呼叫:

因為控制元件除了單個的自定義控制元件外,還有用戶控制元件(UserControl)——實作某些復雜功能的時候,往往就需要用到用戶控制元件,用戶控制元件往往是多個控制元件的組合,所以將控制元件放到一個類別庫中可以方便的呼叫,修改也方便,

啟動VS(本文使用的VS2019),添加新的 類別庫(.NET Framework)專案,起好專案名稱并選好位置,點擊創建,

個人經驗之談

關于框架的選擇,

在實際應用當中,框架版本要根據自定義控制元件所服務的專案去選擇,因為是自定義控制元件,所以兼容性很高,往往.Net 2.0就可以實作絕大部分效果,所以,可以根據具體的專案去選擇框架的版本,當然也可以選一個.Net 2.0,然后在實作完成之后編譯成不同框架版本,

2,添加類

在專案名稱上右擊,選擇添加-類,輸入類名:LTrackBar.cs,確定,

個人經驗之談

關于類名

在起自定義控制元件的名稱時,最好不要和系統控制元件名稱一樣,那樣會導致二義性,平白增加代碼量,

所以可以統一加一個前綴或后綴,如:TextBoxEx,PanelPlus,本文便是統一加上前綴”L“——LTrackBar

3,添加繼承

在添加繼承時,根據具體的需要去選擇不同的繼承,比如要對ComboBox的一拉選項添加不同的顏色,就繼承ComboBox并進行重繪;比如要讓TextBox支持透明,就繼承TextBox進行重寫等等,

在本例的LTrackBar中,通過前文的分析發現很簡單,所以可以繼承基礎的Control類,

(1)添加繼承

在類名后輸入”:Control“

(2)添加參考

上一步里會發現”Control“顯示代表錯誤的波浪線,我們將滑鼠懸浮在上面,在彈出的提示按鈕上點擊,選擇”將參考添加到System.Windows.Forms.dll",然后"Control"下面的波浪線將會消失,并變為淺藍色,

(3)修改可訪問性,

由于是一個單獨的類別庫,并且LTrackBar是一個獨立的控制元件,所以我們需要將類的可訪問性修改為Public,

4,添加自定義屬性

個人經驗之談

關于引數命名

對于公共引數,個人建議添加一個統一的前綴,主要原因有兩點:

1,在視圖設計界面中的屬性視窗中,無論是“按分類排序”還是“按字母排序”,都可以使控制元件所公開的自定義屬性集中在一起,

按分類排序:

按字母排序:

2,在代碼編輯界面,可以在輸入統一的前綴后,將該控制元件的所以自定義屬性都在代碼提示視窗中顯示在一起,方便選擇,

(1)顏色相關

通過前文可知,我們涉及到的顏色有兩個——背景條顏色和滑塊顏色,所以我們添加兩個屬性,其中的“Invalidate()”是為了在修改該屬性值后立刻使控制元件重繪,

(2)圓角相關

(3)最大值與最小值

如TrackBar一樣,我們也需要有最大值和最小值,由于我的需要很簡單,所以只支持整型(int),

首先,最小值應該大于0,然后最小值要小于最大值,所以最小值如下:

其次,最大值也應該大于最小值,

(4)當前值 

用來獲取或設定當前LTrackBar所代表的值,

當前值需要在最大值和最小值之間,同時我們需要知道值發生了變化,所以添加了一個委托事件LValueChanged,關于委托和事件此處不展開講,因為不懂也不影響使用,就像固定公式一樣往上套就行了,只需要知道其作用是讓呼叫本控制元件的人知道當前的值發生了變化,

(5)方向

LTrackBar支持橫向顯示,也支持豎向顯示,

在橫向顯示時,分為兩種情況:1,左端為最小值(L_Minimum),右端為最大值(L_Maximum);2,左端為最大值(L_Maximum),右端為最小值(L_Minimum),

在豎向顯示時,分為兩種情況:1,頂部為最小值(L_Minimum),底部為最大值(L_Maximum);2,頂部為最大值(L_Maximum),底部為最小值(L_Minimum),

綜上,共有4種情況,所以我們先創建一個列舉,

同樣為了方便統一管理,新建一個類專門存放列舉資訊,

之后,創建一個Orientation列舉型別的屬性:

上面的那兩個if陳述句的作用是為了實作在改變方向后,自動交換控制元件的寬和高,

(6)寬度/高度

像TrackBar只能在設計器中調整寬度一樣,LTrackBar也只能調整寬度(橫向顯示時)或高度(豎向顯示),所以需要一個屬性來控制,

為了實作只能調整寬度/高度,需要重寫SetBoundsCore方法,MSDN上關于SetBoundsCore的說明如下:

我們需要對其進行重寫,以限制只能調整寬度或高度:

由于VS的強大,所以在重寫時非常方便:

 

(7)增加描述資訊

在公開屬性上加入Catagory(分組),Description(描述),之后便可以在屬性視窗看到相應的分類和說明,

 

5,添加事件

為了獲取LTrackBar的當前值,以及在值改變時執行某些操作,所以需要增加一個事件,事件資料則為當前值(L_Value),

(1)新建類,繼承自EventArgs,

(2)新建委托和事件

 6,重寫方法

通過前文的分析,我們知道主要用到了GDI+,同時支持滑鼠點擊、拖動,所以我們需要重寫以下這些方法,

其中,OnPaint事件是用來畫顯示界面的,Mouse相關的事件是與實作滑鼠操作相關的,

為了知道當前滑鼠的狀態(進入、離開、按下、松開),需要定義一個列舉:

下面是每個重寫方法的具體說明:

(1)OnMouseEnter方法

標識著滑鼠進入,只需要設定一下滑鼠狀態即可,

(2)OnMouseLeave方法

同上

(3)OnMouseUp方法

同上

 

(4)OnMouseDown方法

當滑鼠點擊了控制元件時會觸發本事件,在滑鼠點擊后,控制元件應該重繪界面,主要是滑塊(Slider)的變化,同時滑塊(Slider)所代表的值也應該發生變化,同時引發LValueChanged事件,

(5)OnMouseMove方法

當滑鼠在控制元件上移動時觸發本事件,在實際操作時都是在在按著滑鼠左鍵并拖動,所以要判斷滑鼠的狀態(mouseStatus)是否是按下(Down),其他同上,

在OnMouseDown和OnMouseMove中,有一個方法:pPointToValue(),其作用便是將滑鼠的坐標值轉換為對應代表的值,其代碼如下:

其代碼很簡單,就是計算滑鼠落點占控制元件寬度/高度的比例,再乘以值的范圍就得到了代表的值,在下文中有示意圖講解,本處不再贅述,

(6)OnPaint方法

本方法是控制元件實作的核心,幾乎只要涉及控制元件重繪和自定義控制元件,都兔不了要重寫OnPaint方法,

在OnPaint方法中,我們主要完成兩部分的操作:

1)畫背景條(Bar)

2)畫滑塊(Slider)

這便是OnPaint方法的完整代碼:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    pValueToPoint();
    e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

    Pen penBarBack = new Pen(_BarColor, _BarSize);
    Pen penBarFore = new Pen(_SliderColor, _BarSize);

    float fCapHalfWidth = 0;
    float fCapWidth =  0;
    if (_IsRound)
    {
        fCapWidth = _BarSize;
        fCapHalfWidth = _BarSize / 2.0f;
        penBarBack.StartCap = LineCap.Round;
        penBarBack.EndCap = LineCap.Round;

        penBarFore.StartCap = LineCap.Round;
        penBarFore.EndCap = LineCap.Round;
    }

    float fPointValue = https://www.cnblogs.com/lesliexin/p/0;
    if (_Orientation == Orientation.Horizontal_LR || _Orientation == Orientation.Horizontal_RL)
    {
        e.Graphics.DrawLine(penBarBack, fCapHalfWidth, Height / 2f, Width - fCapHalfWidth, Height / 2f);

        fPointValue = mousePoint.X;
        if (fPointValue < fCapHalfWidth) fPointValue =https://www.cnblogs.com/lesliexin/p/ fCapHalfWidth;
        if (fPointValue > Width - fCapHalfWidth) fPointValue = https://www.cnblogs.com/lesliexin/p/Width - fCapHalfWidth;
    }
    else
    {
        e.Graphics.DrawLine(penBarBack, Width / 2f, fCapHalfWidth, Width / 2f, Height - fCapHalfWidth);

        fPointValue = mousePoint.Y;
        if (fPointValue < fCapHalfWidth) fPointValue =https://www.cnblogs.com/lesliexin/p/ fCapHalfWidth;
        if (fPointValue > Height - fCapHalfWidth) fPointValue = https://www.cnblogs.com/lesliexin/p/Height - fCapHalfWidth;
    }


    if (_Orientation == Orientation.Horizontal_LR)
    {
        e.Graphics.DrawLine(penBarFore, fCapHalfWidth, Height / 2f, fPointValue, Height / 2f);
    }
    else if (_Orientation == Orientation.Horizontal_RL)
    {
        e.Graphics.DrawLine(penBarFore,  fPointValue, Height / 2f, Width - fCapHalfWidth, Height / 2f);
    }
    else if (_Orientation == Orientation.Vertical_TB)
    {
        e.Graphics.DrawLine(penBarFore, Width / 2f, fCapHalfWidth, Width / 2f, fPointValue);
    }
    else
    {
        e.Graphics.DrawLine(penBarFore, Width / 2f,  fPointValue, Width / 2f, Height - fCapHalfWidth);
    }
}
OnPaint

在OnPain方法用到了一個方法:pValueToPoint(),其作用是將值轉換為相應坐標,代碼如下:

private void pValueToPoint()
{
    float fCapHalfWidth = 0;
    float fCapWidth = 0;
    if (_IsRound)
    {
        fCapWidth = _BarSize;
        fCapHalfWidth = _BarSize / 2.0f;
    }

    float fRatio = Convert.ToSingle(_Value-_Minimum) / (_Maximum - _Minimum);
    if (_Orientation == Orientation.Horizontal_LR)
    {
        float fPointValue = https://www.cnblogs.com/lesliexin/p/fRatio * (Width - fCapWidth) + fCapHalfWidth;
        mousePoint = new PointF(fPointValue, fCapHalfWidth);
    }
    else if (_Orientation == Orientation.Horizontal_RL)
    {
        float fPointValue = https://www.cnblogs.com/lesliexin/p/Width - fCapHalfWidth - fRatio * (Width - fCapWidth);
        mousePoint = new PointF(fPointValue, fCapHalfWidth);
    }
    else if (_Orientation == Orientation.Vertical_TB)
    {
        float fPointValue = https://www.cnblogs.com/lesliexin/p/fRatio * (Height - fCapWidth) + fCapHalfWidth;
        mousePoint = new PointF(fCapHalfWidth, fPointValue);
    }
    else
    {
        float fPointValue = https://www.cnblogs.com/lesliexin/p/Height - fCapHalfWidth - fRatio * (Height - fCapWidth);
        mousePoint = new PointF(fCapHalfWidth, fPointValue);
    }

}
pValueToPoint

之所以沒有注釋,實在是太過淺顯無可注釋,單純的看代碼很難理解,下面我將通過示意圖的方法講解,其實只要看了示意圖,就會恍然大悟,會發現其實很簡單,

7,示意圖解

對于LTrackBar而言,有兩種樣式:直角和圓角,這兩種的實作并沒有太大不同,主要是Pen的LineCap屬性不同,LineCap說明見前文,

(以下將以橫向、從左到右的樣式(_Orientation = Orientation.Horizontal_LR)進行講解,其他類同,不多贅述,)

示意圖1:

我在圖中標注了一些點,主要用來詳解,

上圖中的B點(Rect.B、Round.B)即是當前滑鼠點擊的點,也是代表當前值的點,也是藍色條的寬度,

示意圖2:

在LineCap=Round時,其在繪制的線條兩端會各繪制一個半圓,如上圖中紫色所示,其半圓直徑等于線條寬度,

下面我會講解一下上面那些代碼中的那些算式是怎么來的,

(1)直角

1)計算

已知:

起始點:Rect.A;

結束點:Rect.C;

點Rect.A 對應的值為: L_Minimum;

點Rect.C 對應的值為: L_Maximum;

滑鼠可點擊范圍=控制元件寬度 = Bar.Width;

實際取值范圍 = (L_Maximum-L_Minimum);

滑鼠點擊處的X值=點Rect.B = Slider.Width;

滑鼠點擊處的X值與滑鼠可點擊范圍的比值=該點擊處對應的實際值與取值范圍的比值,即:

對應值/取值范圍=Slider.Width/Bar.Width;

所以:

對應值(_Value)=Slider.Width/Bar.Width*(L_Maximum-L_Minimum);

由于最左側的點Rect.A并不是0,而是對應著L_Minimum,所以,最后得到的真實值(L_Value)=_Value+L_Minimum;

2)繪制
設定Pen的寬度=Bar.Height

所以要從控制元件高度的中間開始繪制,其起終坐標如下:

起點:(Rect.A)=(0,Bar.Height/2);

終點:(Rect.C)=(Bar.Width,Bar.Height/2);

(2)圓角

1)計算

已知:

因為設定了圓角(LineCap=Round),所以線條兩端會各繪制一個半圓(示意圖中紫色半圓所示),其半圓直徑等于線條寬度,

那么其開始點便不再是點Round.A,而是點Round.D,同理,其結束點也不是點Round.C,而是點Round.E,

點Round.D 對應的值為: L_Minimum;

點Round.E 對應的值為: L_Maximum;

滑鼠可點擊范圍=控制元件寬度減去兩個半圓的寬度 = (Bar.Width-Bar.Height);

實際取值范圍 = (L_Maximum-L_Minimum);

滑鼠點擊處的X值 (點Round.B) = (Slider.Width-Bar.Height/2);(注意:此時滑鼠點擊處所產生的視覺效果范圍是(Round.A~Round.F),但其真正移動的范圍是(Round.D~Round.B),)

滑鼠點擊處的X值與滑鼠可點擊范圍的比值=該點擊處對應的實際值與取值范圍的比值,即:

對應值/取值范圍= (Slider.Width-Bar.Height/2)/ (Bar.Width-Bar.Height);

所以:

對應值(_Value)= (Slider.Width-Bar.Height/2)/ (Bar.Width-Bar.Height)*(L_Maximum-L_Minimum);

由于可點擊的最左側的點Round.D對應著L_Minimum,所以,最后得到的真實值(L_Value)=_Value+L_Minimum;

2)繪制

設定Pen的寬度=Bar.Height,所以要從控制元件高度的中間開始繪制,

又因為設定LineCap=Round,導致兩端各繪制了一個半圓,所以其起點和終點的坐標也應減去相應的值:

起點:(Round.D)=(Bar.Height/2,Bar.Height/2);

終點:(Round.E)=(Bar.Width-Bar.Height/2,Bar.Height/2);


 

四,效果演示及調整優化

1,演示

我們在專案上右鍵,選擇生成,之后在同一解決方案下新建一WinForm專案,此時在工具箱的最上層會有我們的自定義控制元件——LTrackBar,

如圖:

 

我們選中并添加到主界面上,并設定相應的屬性,

同時添加一個label,用來顯示當前的值, 

其實效果如下:

在實際運行時,我們會發現在點擊和拖動時,控制元件會有閃爍(由于GIF錄制幀率,所以上面的動圖不看不閃爍),

為了解決閃爍的問題,我們在LTrackBar的建構式上添加對雙緩沖的支持,

個人經驗之談

關于雙緩沖

一般而言,只要涉及到了GDI+,都會使用雙緩沖技術去減少閃爍,而且使用也很簡單,就兩行代碼而已:

SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

當然,ControlStyles還有很多屬性,其作用也各有作用,在以后的文章中如果有用到我會再說明的,

2,默認事件

默認事件,顧名思義,就是雙擊控制元件時自動生成的事件,像雙擊Button時的Click事件,雙擊TextBox時的TextChanged事件等,

要實作這種效果,需要在代碼的最上面加上DefaultEvent事件,如下:

 

 其中“LValueChanged”就是我們要設定的默認事件,這樣在我們雙擊LTrackBar時,便會自動生成該事件,


 

五、結束語

通篇下來,其實可以發現并沒有用到多深的知識,更多的是想像力,解放你的思想,不要被常規所束縛,


 

六、源代碼及工程下載

https://files.cnblogs.com/files/lesliexin/LTrackBar.7z

 

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

標籤:WinForm

上一篇:WinForm版 螢屏截圖

下一篇:Winform ComboBox獨立繪制下拉選項的字體顏色

標籤雲
其他(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