當前位置:編程學習大全網 - 編程語言 - C#中關於PANEL控件的Graphics繪圖

C#中關於PANEL控件的Graphics繪圖

LZ關鍵問題是沒有註意到圖形在某位“位置”繪制後,如果該位置發生的移動,或其他圖形遮擋了後會出現什麽,如下圖:

用其他什麽東西,例如QQ遮擋 了壹下原圖形就沒有了...因為在此之後沒有人重新繪制了該圖形,基於類似原因,即便妳使用了Scoll,也無法看到後面的圖形

妳的程序我改造了壹下,可以根據需求繪制圖形,去掉Panel自帶的HorizontalScroll,新增了壹個hScrollBar(HorizontalScroll沒有嘗試成功,所以替換了,LZ可以多嘗試下)

?private?struct?ImageContainerType

{

public?Rectangle?theImage;?//?圖形容器--矩形

public?SolidBrush?theBrush;//?繪制該圖形所用的畫筆

};

//?繪制的圖形的"容器"--這裏用來存放繪制的矩形

List<ImageContainerType>?imageList;

//?用於控制繪圖位置的全局變量

int?indexDraw?=?0;

private?void?button1_Click(object?sender,?EventArgs?e)

{

/*

調整思路

*?方案A:靜態繪圖

*?1、將所有繪制的圖形保存到imageList容器中

*?2、在需要時再執行繪制,例如拖動Scoll時觸發

*?缺點:如果繪制的圖形較多,將消耗大量內存

*?優點:只需要執行壹次圖形創建過程,以後隨時可以使用,節省CPU或GPU資源

*?且算法簡單

*?

*?方案B:動態繪圖

*?1、先繪制當前所需要的圖形(在可見區間內)

*?2、在需要時如Scoll,重新(在可見區間內)繪制所需要的圖形

*/

int[]?nums?=?new?int[10000];

//?初始化圖形容器

imageList?=?new?List<ImageContainerType>(100);

ImageContainerType?tempImage;

Random?random?=?new?Random();?//隨機數值

for?(int?i?=?0;?i?<?100;?i++)

{

nums[i]?=?random.Next(0,?2);

}

for?(int?i?=?0;?i?<?100;?i++)

{

if?(nums[i]?==?1)

{

SolidBrush?r1?=?new?SolidBrush(Color.Red);//定義單色畫刷

Rectangle?rect?=?new?Rectangle(20?*?i,?0,?10,?50);

//grap.FillRectangle(r1,?rect);//填充這個矩形?

//?將當前圖形存入容器

tempImage?=?new?ImageContainerType();

tempImage.theBrush?=?new?SolidBrush(Color.Red);

tempImage.theImage?=?new?Rectangle(20?*?i,?0,?10,?50);

imageList.Add(tempImage);

}

else

{

SolidBrush?b1?=?new?SolidBrush(Color.Blue);//定義單色畫刷

Rectangle?rect?=?new?Rectangle(20?*?i,?0,?10,?50);

//grap.FillRectangle(b1,?rect);//填充這個矩形

tempImage?=?new?ImageContainerType();

tempImage.theBrush?=?new?SolidBrush(Color.Blue);

tempImage.theImage?=?new?Rectangle(20?*?i,?0,?10,?50);

imageList.Add(tempImage);

}?

}

//?[關鍵]設置Scorll的新值

this.hScrollBar1.Maximum?=?100;

//?繪制全部圖形

DrawImage(0,?imageList.Count?-?1);

MessageBox.Show("繪制完成");

}

///?<summary>

///?實際的圖形繪制方法

///?</summary>

///?<param?name="start">所需繪制圖形的起始編號</param>

///?<param?name="end">所需繪制圖形的結束編號,如果end在start則繪制所有剩下圖形</param>

void?DrawImage(int?start,?int?end)

{?

//?1、判定繪圖容器是否存在

if?(imageList?==?null?||?imageList.Count?<=?0)

{

MessageBox.Show("還沒有生成圖形");

return;

}

//?2、繪圖區間判定

if?(start?>=?imageList.Count?||?end?>=?imageList.Count)

{

MessageBox.Show("不在有效繪圖區間");

return;

}

//?3、

if?(start?<=?end)

{?

//?繪制從起始位置,到結束位置所有圖形

end?=?imageList.Count?-?1;

}

//?4、繪制圖形

Graphics?grap?=?pChart.CreateGraphics();

grap.Clear(Color.White);

Pen?blue?=?new?Pen(Color.Blue);

Pen?red?=?new?Pen(Color.Red);

for(int?index=start;index<=?end;index++)

{

grap.FillRectangle(imageList[index].theBrush,?imageList[index].theImage);

}

}

///?<summary>

///?在Scroll實際中重繪Panel內容

///?</summary>

///?<param?name="sender"></param>

///?<param?name="e"></param>

private?void?hScrollBar1_Scroll(object?sender,?ScrollEventArgs?e)

{

//?每次重繪"當前位置"直至結尾的所有圖形

DrawImage(e.NewValue,?imageList.Count?-?1);

}

得到的效果是:

妳可以看到,Scoll正確發揮了作用,但貌似圖形不正確阿....前面的沒有了?

原因在於現有的重繪訪法是

//?每次重繪"當前位置"直至結尾的所有圖形

DrawImage(e.NewValue,?imageList.Count?-?1);

而在imageList容器中存放的圖形其坐標已經固定了,因此繪制結果也就可以預期了——這距離使用Scoll拖動圖形距離不遠了:>

其實關鍵就是圖形和界面之間相對位置的處理了——界面是靜止的,那麽只有讓圖動起來,看我的改造:

註意上面兩個圖形的坐標,0-99和9~99,然後看相應的圖形。的確界面沒動,但圖形動了,看起來就像是Panel向右滑動了10個單位壹樣。修改Scoll事件中的繪圖方法就可以達到所需要的效果了

///?<summary>

///?在Scroll實際中重繪Panel內容

///?</summary>

///?<param?name="sender"></param>

///?<param?name="e"></param>

private?void?hScrollBar1_Scroll(object?sender,?ScrollEventArgs?e)

{

int?theValue?=?e.NewValue;

int?theNewImageX_Index?=?0;

//?要想實現“動態效果”的關鍵是重新計算圖形與“靜止”的界面

//?之間的相對位置,即“界面不動”圖形動(我不動那就麻煩妳動壹下了:>)

//?這將消耗壹定的CPU資源

//?--嘗試將圖形的位置根據當前"位置"進行移動

//?--將當前圖形設定為"相對於界面"的第壹個圖形,後面的圖形依次+1

for?(int?index?=?theValue;?index?<?imageList.Count;?index++)

{

ImageContainerType?temp?=?new?ImageContainerType();

temp.theImage?=?new?Rectangle(20?*?theNewImageX_Index,?0,?10,?50);

temp.theBrush?=?imageList[index].theBrush;

imageList[index]?=?temp;

theNewImageX_Index++;

}

//?然後重新繪制圖形

DrawImage(theValue,?imageList.Count?-?1);

} 這裏最關鍵的就是重新計算圖形的坐標

new?Rectangle(20?*?theNewImageX_Index,?0,?10,?50);

  • 上一篇:火影忍者遊戲秘籍
  • 下一篇:PA8000功率分析儀支持電機的矩角特性測試功能嗎?
  • copyright 2024編程學習大全網