Copyright © 2003-2009
By Suthep Sangvirotjanaphat
  Mobile: 089-967-2200, 081-915-7816
Phone: 0-2992-4877   Fax: 0-2992-4878
Fast Contact Us
^
%
.

GreatFriends.Biz Community

Custom Search
 MESSAGE #99059 (อ่าน 1,229 ครั้ง)

สร้าง Chart Control ไว้ใช้งานแบบเศรษฐกิจพอเพียง (2)

Tags: Windows, VB, .NET 2, .NET 3.0, .NET 3.5, VS 2005, VS 2008, Article
ต่อเนื่องจากความเดิมตอนที่แล้ว
 

Neo ได้ค้นพบและเรียนรู้จนเข้าใจในความเป็น the Metrix ....
ไม่ใช่....นั่นมันหนัง (เพิ่งซื้อ ไตรภาคมาดู)

ตอนที่แล้วเราหยุดกันที่การสร้าง BarItem ขึ้นมาแล้วทำการเอา TableLayoutPanel มาเป็นตัวจัดระเบียบ
ซึ่งเวลาใช้งานจริง ๆ อาจจะลำบาก เพราะบางทีเราอาจจะไม่รู้ว่า จำนวน Bar ที่จะแสดงผลมีกี่อันกันแน่

เพราะงั๊นเราจะทำการเขียน Code เพื่อให้เราไปงานง่าย ๆ เลยดังนี้ครับ

นั้นคือการสร้าง User Control ขึ้นมาอีกตัวที่จะใช้บรรจุ BarItem อีกที
เวลาเราใช้งานเราก็ใช้ตัวนี้แหล่ะครับ
 

ผมตั้งชื่อว่า BarChart

จากนั้น ลาก TableLayoutPanel มาวางไว้ 1 ตัว
แล้วก็ Set Property ColumnCount และ RowCount ให้เป็น 1 รอไว้ก่อน
เดี๋ยวเราจะสร้าง Property ไว้รอ แล้วค่อยมา Add BarItem ตามจำนวนใน code เอาครับ
ที่ขาดไม่ได้คือต้อง Set Dock ให้เป็น Fill ด้วย นั่นคือให้ TableLayoutPanel ขยายตัวให้เต็มเนื้อที่ทั้งหมดเลย
อ่อ ๆ ๆ....
ในที่นี้ผมทำการเปลี่ยน BackColor ของ BarChart หรือตัว UserControl ให้เป็นสีขาวด้วยครับ

 

ว่าถึงเรื่องสีแล้ว
ขอย้อนกลับไปที่ BarItem อีกที เพื่อไปเพิ่ม Property อีกตัวนึงเพื่อทำการเปลี่ยนสีพื้นของ BarItem ได้ด้วย
ไม่ใช่สีของ Bar แท่งนะครับ เพราะสีแท่งเรามีสร้าง Property ไว้แล้ว แต่คราวนี้จะเป็นสีพื้น
ด้วย Property นี้ครับ
............................................................................................................................................
Public Property BGColor() As Color
    Get

        Return Me.pBar.BackColor
    End Get
    Set(ByVal value As Color)
        Me.pBar.BackColor = value
    End Set
End Property
............................................................................................................................................

เราไม่จำเป็นต้องประกาศตัวแปรเพิ่มเพื่อเก็บสีนะครับ เพราะเราจะใช้สีของ Panel เลย
เสร็จแล้วกลับมาที่ BarChart เหมือนเดิมครับ
ที่นี่เราจะสร้างตัวแปรต่าง ๆ ที่จำเป็นดังนี้
............................................................................................................................................
    Private maximum As Integer
    Private bItem As List(Of BarItem)
    Private itemBGColor As Color
............................................................................................................................................

โดยที่

    maximum  ใช้เก็บค่าสูงสุดของทุก ๆ BarItem ซึ่งมันจะต้องเหมือนกัน
  จริง ๆ เราอาจจะอ้างที่ BarItem ใด ๆ ซักอันก็ได้
  แต่กลัวเวลากลับมาอ่าน Code มันจะดูยากครับ
    bItem   อันนี้จะเป็นตัวแปรแบบ List of โดยสร้างให้เป็น List of BarItem
  ใช้เพื่ออ้างอิง BarItem แต่ละตัวแบบง่าย ๆ โดยใช้ Index ครับ
    itemBGColor  อันนี้ที่เพิ่งไปเติมมา คือใช้เป็นสีของ Background ของ BarItem แต่ละตัว
  ลักษณะการอ้างอิงเป็นแนว ๆ เดียวกับ maximum ครับ

จากนั้น
เราจะเริ่ม code แรกกันที่ New ครับ
............................................................................................................................................
Public Sub New()
    Dim _item As New BarItem()

    InitializeComponent()

    Me.maximum = 100
    Me.itemBGColor = Color.Aqua

    Me.bItem = New List(Of BarItem)
    _item.Maximum = Me.maximum
    _item.CurrentValue = 10
    _item.Dock = DockStyle.Fill
    _item.BGColor = Me.itemBGColor
    Me.bItem.Add(_item)

    Me.tbItem.ColumnCount = 1
    Me.tbItem.Controls.Add(_item, 0, 0)

    Me.tbItem.ColumnStyles.Clear()
    Me.tbItem.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))

End Sub
............................................................................................................................................

ใน Sub New นี้ ผมได้มีการกำหนดค่าเริ่มต้นต่าง ๆ ไปแล้วเรียบร้อย รวมถึงสร้าง BarItem ไว้รอ 1 อันด้วย
โดยที่สังเกตุจาก code จะมีการ Add _item เข้าถึง 2 จุดคือ
............................................................................................................................................
    Me.bItem.Add(_item)
    Me.tbItem.Controls.Add(_item, 0, 0)
............................................................................................................................................

เกิดข้อสงสัยว่า Add เข้า TableLayoutPanel แค่อย่างเดียวไม่ได้เหรอ แล้วเวลาอ้างถึง ไปวิ่งอ้างในนั้นเอา
ตอบว่า : ก็ได้ครับ แต่มันจะอ่านยาก และการวิ่งลูปไปใน TableLayoutPanel ที่เก็บอะไรก็ได้ในนั้น
มันจะต้องมีการ Cast Object มาเป็น BarItem อีกทีเ เพราะเวลา TableLayoutPanel มัน return ออกมามันจะเป็น Object
แล้วก็เหมือนเดิมคือ

กลับมาอ่านยาก

เลยแก้ปัญหาด้วยการเพิ่มตัวแปรแบบ List of BarItem แทน จะได้ใช้กันง่าย ๆ ครับ
ส่วนอีกส่วนนึง
............................................................................................................................................
    Me.tbItem.ColumnStyles.Clear()
    Me.tbItem.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))
............................................................................................................................................

อันนี้จะเป็นการ Set ในส่วนของขนาดของแต่ละ Column ที่ในบทความแรกที่เราใช้การ Click เอาครับ
ต่อไปจะเป็นส่วนของ Property ต่าง ๆ ครับ
............................................................................................................................................
Public Property MaximunValue() As Integer
    Get
        Return Me.maximum
    End Get
    Set(ByVal value As Integer)
        If Not (value = Me.maximum) Then
            Me.maximum = value
            For Each b As BarItem In Me.bItem
                b.Maximum = value                   
            Next
        End If
    End Set
End Property

 

Public Property BarItemColor() As Color
    Get
        Return Me.itemBGColor
    End Get
    Set(ByVal value As Color)
        If Not (Me.itemBGColor = value) Then
            Me.itemBGColor = value
            For Each bItem As BarItem In Me.bItem
                bItem.BGColor = Me.BarItemColor
            Next
        End If
    End Set
End Property
............................................................................................................................................
Property ทั้ง 2 ตัวที่เห็นจะมีการวนลูปเพื่อไล่ Set ค่าที่กำหนดให้ BarItem แต่ละตัวครับ
โดยก่อนวนลูป ผมจะทำการตรวจสอบก่อนว่า ค่าเดิมกะค่าใหม่เท่ากันหรือเปล่า
ถ้าเท่าจะได้ไม่เสียเวลาไปวนลูป เพราะวนไปมันก็เหมือนเดิม

Property ยังไม่ครบนะครับ แต่ขอผ่านไปก่อน
มาดูในส่วนของการอ้างถึง BarItem แต่ละตัวจากข้างนอกก่อนครับ
............................................................................................................................................
Public Function GetBarItem(ByVal index As Integer) As BarItem
    If (index >= 0) AndAlso (index < Me.bItem.Count) Then
        Return Me.bItem(index)
    Else
        Return Nothing
    End If
End Function
............................................................................................................................................
อันนี้จะเป็น function ที่ใช้ในการอ้างถึง BarItem โดยใช้ index เป็นตัวชี้ครับ
อย่าลืมนะครับ Index เริ่มจาก 0

จากนั้น....
มาดู Property อีกตัวที่ข้ามไว้
ซึ่งเป็นหัวใจของ BarChart เลยครับ
............................................................................................................................................
Public Property BarItemCount() As Integer
    Get
        Return Me.tbItem.ColumnCount
    End Get
 '...................................................................................................
    Set(ByVal value As Integer)
        Dim iBeforeCount As Integer = Me.tbItem.ColumnCount
        '..............................
        If value = iBeforeCount Then
            Return
        End If
        '..............................
        Me.tbItem.Visible = False
        '..............................
        Me.tbItem.ColumnStyles.Clear()
        '..............................
        If value > iBeforeCount Then
            Me.tbItem.ColumnCount = value
            iBeforeCount += 1
            For i As Integer = iBeforeCount To value
                Dim _item As New BarItem()
                _item.Maximum = Me.maximum
                _item.CurrentValue = 10
                _item.Dock = DockStyle.Fill
                _item.BGColor = Me.itemBGColor
    
                Me.bItem.Add(_item) 
                Me.tbItem.Controls.Add(_item, i - 1, 0)
            Next
        Else
            iBeforeCount -= 1
            For i As Integer = iBeforeCount To value Step -1
                Me.bItem.RemoveAt(i)
                Me.tbItem.Controls.RemoveAt(i)
            Next
            Me.tbItem.ColumnCount = value
        End If
        '...................................................

        Dim sAVG As Single = 100 / Me.tbItem.ColumnCount

        For i As Integer = 1 To Me.tbItem.ColumnCount
            Me.tbItem.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, sAVG))
        Next
        Me.tbItem.Visible = True
    End Set
 '...................................................................................................
End Property
............................................................................................................................................
ในส่วนนี้ค่อนข้างวุ่นวายพอสมควร
เพราะจะต้องมีการเพิ่มหรือลดจำนวน Column ให้ตรงตามค่าที่ส่งมา
นอกจากนั้นยังต้องสร้างหรือลด BarItem พร้อมทั้งกำหนดค่าเริ่มต้นให้อีกด้วย

มีจุดสังเกตุที่ code นี้ครับ
............................................................................................................................................
 Me.tbItem.Visible = false
 ...
 ....
 ...
 Me.tbItem.Visible = true
............................................................................................................................................

ถามว่าทำไปทำไม
ตรงนี้จะช่วยลดภาระการ Render Control ครับ เพราะถ้าแสดงผลตลอด จะทำให้ทำงานช้า
เพราะต้องวาด Control ทุกครั้งที่มีการเปลี่ยนแปลง
ดังนั้นผมจึง ซ่อน มันไว้ซะก่อน ให้ทำให้เสร็จ แล้วค่อยแสดงมาทีเดียว
ยังไงตรงนี้ถ้าไม่เคลียร์ว่า.... ผมเอาอะไรมาให้อ่าน

ก็ลองเอา 2 บรรทัดนี้ออกครับ
แล้วลอง Run Program ดูความแตกต่างครับ
อ่อ..แต่รอให้เราทำอะไรให้เสร็จเรียบร้อยก่อนนะครับ ค่อยลอง

เอาล่ะ ทีนี้
ReBuild Project 1 ครั้งครับ
เพื่อให้ Control เรา Update ก่อนครับ

ได้เวลาลองของและ
มาที่ Form ที่เราจะทำการทดสอบครับ
 
 

จัด Form ให้ได้ตามรูปนะครับ
โดยจะมี BarChart 1 ตัวอยู่กลาง Form
มี NumericUpDown 1 ตัวใช้เพื่อกำหนดจำนวนของ BatItem ครับ โดยที่จะมี 1 Button ไว้กดเพื่อสั่งการ
ข้างล่าง ๆ จะมีอีก 1 Button ผมใช้เพื่อกำหนดค่าให้ BarItem แต่ละตัว โดยการสุ่มครับ
แต่ละตัวผมตั้งชื่อแบบนี้ครับ

NumericUpDown  = nBar
BarChart   = BarChart1
Button 1   = cmdSetBar
Button 2   = cmdRandom

มาดูการทำงานกัน
............................................................................................................................................
Private Sub cmdSetBar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSetBar.Click
    ' Set จำนวน Column
    BarChart1.BarItemCount = nBar.Value
End Sub
 '............................................................................................................................
Private Sub cmdRandom_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRandom.Click
    ' ประกาศตัวแปรแบบ Random ไว้สุ่มค่า
    Dim rnd As New Random(Now.Millisecond)

    For i As Integer = 1 To BarChart1.BarItemCount
        Dim bItem As BarItem = BarChart1.GetBarItem(i - 1)

        bItem.CurrentValue = rnd.Next(1, 100)       ' สุ่มค่าตั้งแต่ 1 - 100
        bItem.BarColor = Color.FromArgb(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255))  ' สุ่มค่าสี RGB
        bItem.Caption = i.ToString()        ' อันนี้ Set Caption ของ BarItem แต่ละตัว
    Next
 
End Sub
............................................................................................................................................

 
จากนั้นลอง Run ดูผลครับ
อย่าลืมว่า ถ้ายังงงเรื่อง Visible ที่ติดไว้
ก็ลอง Comment Code ทั้ง 2 บรรทัดนั้น
แล้วลอง Run อีกทีดูครับ
 
 

วันนี้เยอะและ
บางคนที่อ่านคงนึกในใจ

ยังไม่จบอีกเร๊อะ.....
จริง ๆ มันจบแล้วก็ได้
แต่มันยังไม่สุดครับ
เพราะผมจะทำไตรภาค แบบ The Metrix
สำหรับตอนนี้จบภาค Reload ก่อนครับ
เดี๋ยวคราวหน้าเจอ The Metrix Revolution เป็นตอนจบครับ



SuperTee วันที่ส่ง: 15 ม.ค. 52 15:54 GMT+7
วันที่ปรับล่าสุด: 12 ก.พ. 52 03:05 GMT+7
REPLY #1 (99060)

อย่าลืมลองเปลี่ยน Property BarItemColor ดูด้วยนะครับ จะได้ดูมีมิติมากขึ้น

เดี๋ยวตอนหน้าจะโพส File Project ให้นะครับ
เพราะมันยังไม่เสร็จ


SuperTee วันที่ส่ง: 15 ม.ค. 52 15:58 GMT+7
วันที่ปรับล่าสุด: 15 ม.ค. 52 15:58 GMT+7
REPLY #2 (99062)
 เช่นเดิม


nano วันที่ส่ง: 15 ม.ค. 52 16:20 GMT+7
วันที่ปรับล่าสุด: 15 ม.ค. 52 16:20 GMT+7
REPLY #3 (99077)


MR.L วันที่ส่ง: 15 ม.ค. 52 18:51 GMT+7
วันที่ปรับล่าสุด: 15 ม.ค. 52 18:51 GMT+7
REPLY #4 (99087)
(ไร้คำบรรยาย)


zrea วันที่ส่ง: 15 ม.ค. 52 22:54 GMT+7
วันที่ปรับล่าสุด: 15 ม.ค. 52 22:54 GMT+7
REPLY #5 (99089)

เสริมนิดนึงครับ

เนื่องจากผมให้ข้อมูลเรื่องการกำหนด Property ของ TableLayoutPanel ไม่ครบ
ส่วนที่ต้องปรับแต่งเพิ่มเติมคือ
 
GrowStyle = AddColumns
 
ครับ


SuperTee วันที่ส่ง: 15 ม.ค. 52 23:01 GMT+7
วันที่ปรับล่าสุด: 15 ม.ค. 52 23:01 GMT+7
REPLY #6 (99090)

มีอะไรเพิ่มเติมก็

แนะนำมาเลยนะครับ
เผื่อจะได้ปรับให้มันดีขึ้นไปอีก


SuperTee วันที่ส่ง: 15 ม.ค. 52 23:02 GMT+7
วันที่ปรับล่าสุด: 15 ม.ค. 52 23:02 GMT+7
REPLY #7 (99107)

สุดยอดครับพี่

ขอสัมภาษณ์ด้วยเลยนะครับ 
1 ทำไมถึงคิดทำคอนโทรลตัวนี้ครับ
2 เอาเวลาส่วนไหนทำ แบ่งเวลาทำงาน กับ เวลาส่วนตัวยังไง
3 การจะทำคอนโทรลแบบนี้ หรือว่าแบบอื่น จะรู้ได้ไงว่าควรกำหนดproperty อะไรบ้าง มี่ส่วนประกอบอะไรบ้าง
ปล. เพื่อจะคิดแบบนี้บ้าง


army2543 วันที่ส่ง: 16 ม.ค. 52 11:03 GMT+7
วันที่ปรับล่าสุด: 16 ม.ค. 52 11:03 GMT+7
REPLY #8 (99110)
เยี่ยมเหมือนเดิมครับ


*aeed* วันที่ส่ง: 16 ม.ค. 52 11:11 GMT+7
วันที่ปรับล่าสุด: 16 ม.ค. 52 11:11 GMT+7
REPLY #9 (99112)
ขอตอบนะครับ
 
1 ทำไมถึงคิดทำคอนโทรลตัวนี้ครับ
    ก่อนหน้าตัวนี้ เขียนแบบ GD+ ครับ เพราะรายละเอียดมันเยอะกว่านี้มาก หลังจากเสร็จแล้ว กลับมานั่งมองดูว่า น่าจะทำตัวง่าย ๆ มาเล่น ๆ ซะตัวนึง แล้วเห็นในนี้ก็ถามกันเป็นระยะ ๆ เป็น Dejavu เลย ก็เลยเอาซะเลย แต่มันก็ไม่ได้เก่งอะไรมากนะครับ ถ้าแสดงผลธรรมดา ๆ ก็โอเคนะผมว่า
 
2 เอาเวลาส่วนไหนทำ แบ่งเวลาทำงาน กับ เวลาส่วนตัวยังไง
    มันก็งานแหล่ะครับ (อ้างได้ว่าเป็นงาน) งานผมพักหลังจะแนว ๆ ที่ชาวบ้านเค้าไม่ทำกันมากกว่า พอทำเสร็จก็เอาไปนั่งดู นั่ง Discuss กันว่ามันโอเคมั๊ย แค่นั้น แต่ก็ต้องปลีกเวลามานั่งทำครับ เพราะงานอื่น ๆ ก็มี ที่ยากกว่าก็คือ คิดยังไง ให้มันง่าย Codeง่าย, ดูง่าย และเรียกใช้ง่าย
 
3 การจะทำคอนโทรลแบบนี้ หรือว่าแบบอื่น จะรู้ได้ไงว่าควรกำหนดproperty อะไรบ้าง มี่ส่วนประกอบอะไรบ้าง
    มาจากการลองใช้ของชาวบ้านเค้าครับ รวมทั้งระหว่างทำก็เพิ่มๆ ไปเรื่อย ๆ คือต้องเข้าใจก่อนว่า พวกแบบนี้ทำครั้งเดียวจบยากครับ ยิ่งเจอแนว ๆ Change Spec All the Time ยิ่งต้องดักคอกันไว้ก่อนล่วงหน้า มันเปลี่ยนมาเราก็ ชิว ๆ (ถ้า Code ดักคอไว้แล้ว)
 
........................................................................................................................................................................................
 
สำคัญต้องทะลึ่งครับ (ไม่ใช่เรื่องอย่างว่านะ ... แต่ขอร้อง อย่าพิสูจน์)
ทะลึ่งคิด.... แล้วคิดแล้วต้องทำด้วย


SuperTee วันที่ส่ง: 16 ม.ค. 52 11:19 GMT+7
วันที่ปรับล่าสุด: 16 ม.ค. 52 11:19 GMT+7
REPLY #10 (99113)

อืม  ต้องหาเวลาหัดทะลึ่งมั่งแฮะ  ขอบคุณมากครับพี่



army2543 วันที่ส่ง: 16 ม.ค. 52 11:42 GMT+7
วันที่ปรับล่าสุด: 16 ม.ค. 52 11:42 GMT+7
REPLY #11 (99360)
สู้ ๆ ปรบมือให้ครับ


V# Guy วันที่ส่ง: 19 ม.ค. 52 18:18 GMT+7
วันที่ปรับล่าสุด: 19 ม.ค. 52 18:18 GMT+7
REPLY #12 (100843)
ขอบคุณคับ


ssm วันที่ส่ง: 12 ก.พ. 52 03:05 GMT+7
วันที่ปรับล่าสุด: 12 ก.พ. 52 03:05 GMT+7
กระทู้นี้มีอายุเกิน 365 วันแล้ว ท่านจะไม่สามารถตอบกระทู้นี้ได้อีก
ถ้าต้องการสนทนาต่อ กรุณาตั้งเป็นกระทู้ใหม่ได้ในหน้าโฮม
และอาจจะอ้างถึงกระทู้นี้ โดยก๊อปปี้ข้อความในกล่องสีขาวด้านล่างไปแปะในกระทู้ใหม่

copy เพื่ออ้างอิงถึงข้อความนี้:
สร้าง Chart Control ไว้ใช้งานแบบเศรษฐกิจพอเพียง (2)
http://greatfriends.biz?99059


8 ก.ย. 20:06
Online: 136