二月 21

繼承建構子(Constructor),這看起來既有學問又深奧的文字

不要怕,以下我用白話文解釋一下

把繼承建構子分解後,就是 繼承 + 建構子

繼承,相信有物件導向概念的朋友應該都知道這2個字的意思

建構子(Constructor),就是用來進行物件初始化的方法

一般來說,Class B 繼承 Class A 之後就可以使用Class A所開放出來的東西

那麼如果Class B 繼承 Class A後,想要對Class A進行初始化的動作,那就需要使用繼承建構子了

先來看看程式吧,看程式就比較不會那麼文謅謅了。程式碼可於這邊下載(C#、VB.NET雙版本)

首先有一個最基本的Class,我們叫它Class A

C#版本Class A

class ClassA
{
    public ClassA()
    {
        _InitString = "123";
    }

    public ClassA(string initStr)
    {
        _InitString = initStr;
    }

    private string _InitString;
    public string InitString
    {
        get { return _InitString; }
    }

    public void ShowClassAInit()
    {
        Console.WriteLine(InitString);
        Console.WriteLine("-----------------------------");
    }
}

VB.NET版本Class A

Class ClassA
    Public Sub New()
        _InitString = "123"
    End Sub

    Public Sub New(ByVal initStr As String)
        _InitString = initStr
    End Sub

    Private _InitString As String
    Public ReadOnly Property InitString() As String
        Get
            Return _InitString
        End Get
    End Property

    Public Sub ShowClassAInit()
        Console.WriteLine(InitString)
        Console.WriteLine("-----------------------------")
    End Sub
End Class

接下來我們需要Class B來繼承Class A

注意到了嗎,繼承建構子的實作方式就是於Class B加入一個與Class A一樣的初始建構子

並使用base(C#語法)、MyBase.New(VB.NET語法)把初始值帶入Class A。成功於Class B內,進行初始化Class A的動作

C#版本Class B

class ClassB : ClassA
{
    public ClassB()
    {
    }

    public ClassB(string initStr)
        : base(initStr)
    {
    }
}

VB.NET版本Class B

Class ClassB
    Inherits ClassA

    Public Sub New()
    End Sub

    Public Sub New(ByVal initStr As String)
        MyBase.New(initStr)
    End Sub

End Class

接下來就看看怎麼使用,跟使用的結果吧
下面使用Console來DemoC#版本Console


class Program
{
    static void Main(string[] args)
    {
        ClassA CA1 = new ClassA();
        Console.WriteLine("new ClassA()");
        CA1.ShowClassAInit(); //Result:123

        ClassA CA2 = new ClassA("Init AAA");
        Console.WriteLine("new ClassA(\"Init AAA\")");
        CA2.ShowClassAInit(); //Result:Init AAA

        ClassB CB1 = new ClassB();
        Console.WriteLine("new ClassB()");
        CB1.ShowClassAInit(); //Result:123

        ClassB CB2 = new ClassB("Init BBB");
        Console.WriteLine("new ClassB(\"Init BBB\")");
        CB2.ShowClassAInit(); //Result:Init BBB

        Console.ReadLine();
    }
}

VB.NET版本Console


Module Module1

    Sub Main()
        Dim CA1 As New ClassA()
        Console.WriteLine("new ClassA()")
        CA1.ShowClassAInit()  'Result:123

        Dim CA2 As New ClassA("Init AAA")
        Console.WriteLine("new ClassA(""Init AAA"")")
        CA2.ShowClassAInit()  'Result:Init AAA

        Dim CB1 As New ClassB
        Console.WriteLine("new ClassB()")
        CB1.ShowClassAInit()  'Result:123

        Dim CB2 As New ClassB("Init BBB")
        Console.WriteLine("new ClassB(""Init BBB"")")
        CB2.ShowClassAInit()  'Result:Init BBB

        Console.ReadLine()

    End Sub

End Module

執行結果如下圖
20110221_1

以上程式碼可於這邊下載(C#、VB.NET雙版本)





十一月 24

有寫過C#的朋友大概都知道,要在C#中輸入一段有斷行的字串或SQL時

都會使用「@」這個好用的符號。好處就是可以直接斷行

例如:
string test = @"
select * from tb
where c1 = 123″

但是在VB.NET就要很鱉腳用 「 & _ 」來斷行
例如:
dim test as string
test = “select * from tb" & _
“where c1 = 123″

如果行數一多,那可真是累死人不償命又無聊的工程
某天在黑暗執行緒的某一篇文章挖到了寶

使用VB.NET 2008內建的XML嵌入語法,來達成模擬C#的「@」
直接看下面的例子

        Dim JS As String = <s><![CDATA[
                <script type="text/javascript">
                jQuery(function ($) {
                    $('#@txtbox.ClientID@').datepicker({
                    rangeSelect: true,
                    firstDay: 1,
                    changeMonth: true,
                    changeYear: true,
                    showOn: 'both',
                    buttonImageOnly: true,
                    buttonImage: '@Context.Request.ApplicationPath@/Picture/calendar.gif'
                    });
                });
                </script>
        ]]></s>.Value.Replace(vbLf, vbCrLf)

跟據Ark網友的補充,由於預設的換行是vbLf,所以後面我加了Replace(vbLf, vbCrLf)
來把換行符號變成vbCrLf

那如果字串裡面有變數怎麼辦?
先把變數用@包起來,例如:@txtbox.ClientID@
之後再用Replace去把變數塞進去,例如:JS = JS.Replace(“@txtbox.ClientID@", “AAAA")

看來一切都很完美了,不過還沒結束
當你在VS2010上使用時你會發現字串內的文字是接近白色的
這對老人家的眼力是很大的考驗
20101124_1

這時候可以進去選項裡面調整

20101124_2

選擇字型與色形,再挑選VB XML CData 區段,調整你想要顏色,按下確定

20101124_3

收工

20101124_4





十一月 09

如果你有寫公用程式讓使用者使用,也許經過版本的更新
有些方法、函式已經過時或過期了
你不再建議使用者繼續使用,而是改用新的方法
這時候要怎麼提示使用者呢?

答案就是使用 Obsolete 這個屬性
先來看看範例程式碼

VB.NET 的語法如下

    Partial Public Class GetDirectoryFiles
        ''' <summary>
        ''' 取得資料夾與檔案
        ''' </summary>
        ''' <returns>String</returns>
        ''' <remarks></remarks>
        <Obsolete("這個方法已經過時了,建議使用新的方法GetDF()")> _
        Public Function GetDirectoryFile() As String
            Return ""
        End Function
    End Class

C# 的語法如下

public partial class GetDirectoryFiles
{
	/// <summary>
	/// 取得資料夾與檔案
	/// </summary>
	/// <returns>String</returns>
	/// <remarks></remarks>
	[Obsolete("這個方法已經過時了,建議使用新的方法GetDF()")]
	public string GetDirectoryFile()
	{
		return "";
	}
}

當使用者使用到這個方法、函式就會出現下面的提示
提示使用者需要注意一下
20101109_1





十一月 23

在GridView中如果想要在滑鼠移動時,滑鼠所指到的那一列會變色的話可以用JavaScript來達成

效果就像下面的圖所示,滑鼠所指到的那一列會變成亮黃色,移開後再還原成原本的顏色

20091123_1

20091123_2

以下為程式碼片段,於RowDataBound的事件中綁定JavaScript到Row中

    Private Sub GridView1_RowDataBound(ByVal sender As Object, _
              ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _
              Handles GridView1.RowDataBound
        '滑鼠移入移出效果。
        If e.Row.RowType = DataControlRowType.DataRow Then
            e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=currentcolor;")
            e.Row.Attributes.Add("onmouseover", "currentcolor=this.style.backgroundColor; this.style.backgroundColor='#ffff40';")
        End If
    End Sub




十一月 13

什麼是擴充方法(Extension Method)呢?

簡單的說就是可以讓你自已擴充用的東西(有說跟沒說一樣…..)

不用把擴充方法想的太難,它其實也是很平易近人的

在寫程式的時候,在字串的後面點(.)下去,會跑出一堆方法讓你使用,最常見的就是ToString()

那麼我們要如何自行設計一個屬於自己的方法呢(結果如下圖)?其實不難

20091113_1

下程的範例程式(專案打包點我下載),研究一下應該就可以懂了

首先撰寫要自訂擴充的方法 ModuleExt.vb

這邊需要注意的地方,在於傳入的參數型態

如果傳入的參數型態是Integer,那麼只有型態是Integer的點下去才會出這個自訂的Method

如果想要任何型態點下去,都會帶出現我們自定的Method,

那麼就把型態定為Object就可以了(如本例的AddString)

Imports System.Runtime.CompilerServices

Namespace ExtensionMethods
    Module OtherExtensions

        '''
''' 英文字首轉大寫
        '''
        <Extension()> _
        Public Function ToUpperFirstWord(ByVal src As String) As String
            If src.Length >= 1 Then
                Dim FirstWord As String = src.Substring(0, 1).ToUpper
                src = src.Remove(0, 1).Insert(0, FirstWord)
            End If
            Return src
        End Function

        <Extension()> _
        Public Function ToPerCent(ByVal src As Double) As String
            Return src * 100 & "%"
        End Function

        <Extension()> _
        Public Function AddString(ByVal src As Object) As String
            Return src & " New AddString"
        End Function

    End Module
End Namespace

接下來則是在要使用的程式頁面引用之前所寫的Extension

Imports ConsoleApplicationTEST.ExtensionMethods.OtherExtensions

Module Module1

    Sub Main()
        Dim test As String = "abcd"
        'Output: Abcd
        Console.WriteLine(test.ToUpperFirstWord)
        'Output: abcd New AddString
        Console.WriteLine(test.AddString)
        'Output: Abcd New AddString
        Console.WriteLine(test.ToUpperFirstWord.AddString)

        'Output: 50%
        Dim testint As Double = 0.5
        Console.WriteLine(testint.ToPerCent)

        Console.ReadLine()
    End Sub

End Module

相關文章:
何謂擴充方法 (Extension method )?
C# 3.0 初體驗:Extension Method
[C#] 3.0 中的新功能 – 擴充方法(Extension Method)





九月 16

PropertyGrid 這個元件在市面上 .net  的書很少看到

這幾天摸了一下,感覺上是個還不錯用的元件

尤其對於在開發"編輯環境"的特別好用

簡單的說,這是一個可以幫你把Class變成設定介面的元件

把Class丟進元件後,元件就會幫你處理傳值與顯示值的問題

看圖或許比較好理解

有沒有一種很熟悉的感覺,沒錯,跟 Visual Studio .Net 的的屬性設定是一樣的

而這個介面只要把寫好的Class放進去就可以自動產生了,真的超方便

完整的程式碼可以到這邊下載

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles MyBase.Load
        '把Class丟進去PropertyGrid
        PropertyGrid1.SelectedObject = New SampleClass
    End Sub

SampleClass.vb

Imports System.ComponentModel

Public Class SampleClass

    <FlagsAttribute()> _
   Public Enum Permissions
        <Description("未設定")> _
        None = 0

        <Description("建立")> _
        Create = 1

        <Description("讀取")> _
        Read = 2

        <Description("更新")> _
        Update = 4

        <Description("刪除")> _
        Delete = 8

        <Description("所有功能")> _
        All = Create Or Read Or Update Or Delete

    End Enum

    Private _P1 As String
    Public Property P1_String() As String
        Get
            Return _P1
        End Get
        Set(ByVal value As String)
            _P1 = value
        End Set
    End Property

    Private _P2 As Integer
    Public Property P2_Integer() As Integer
        Get
            Return _P2
        End Get
        Set(ByVal value As Integer)
            _P2 = value
        End Set
    End Property

    Private _P3 As Boolean
    Public Property P3_Boolen() As Boolean
        Get
            Return _P3
        End Get
        Set(ByVal value As Boolean)
            _P3 = value
        End Set
    End Property

    Private _P4 As DateTime
    Public Property P4_DateTime() As DateTime
        Get
            Return _P4
        End Get
        Set(ByVal value As DateTime)
            _P4 = value
        End Set
    End Property

    Private _P5 As Permissions
    Public Property P5_Enum() As Permissions
        Get
            Return _P5
        End Get
        Set(ByVal value As Permissions)
            _P5 = value
        End Set
    End Property

    Private _P6 As New PropertyTreeClass.AddressType
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    <Description("住址")> _
    Public Property P6_Tree() As PropertyTreeClass.AddressType
        Get
            Return _P6
        End Get
        Set(ByVal value As PropertyTreeClass.AddressType)
            _P6 = value
        End Set
    End Property

    Private _P7 As Color = Color.White
    Public Property P7_Color() As Color
        Get
            Return _P7
        End Get
        Set(ByVal value As Color)
            _P7 = value
        End Set
    End Property

    Private _P8 As Color = System.Drawing.Color.FromArgb(123, 123, 123)
    <Description("於自訂項目的下面空格中按下滑鼠右鍵,可自訂RGB")> _
    Public Property P8_Color() As Color
        Get
            Return _P8
        End Get
        Set(ByVal value As Color)
            _P8 = value
        End Set
    End Property

#Region "可分類的屬性"
    Private _C1 As String
    <Category("分類")> _
    <Description("相同類型的屬性C1")> _
    Public Property C1() As String
        Get
            Return _C1
        End Get
        Set(ByVal value As String)
            _C1 = value
        End Set
    End Property

    Private _C2 As String
    <Category("分類")> _
    <Description("相同類型的屬性C2")> _
    Public Property C2() As String
        Get
            Return _C2
        End Get
        Set(ByVal value As String)
            _C2 = value
        End Set
    End Property
#End Region

End Class

PropertyTreeClass.vb

Imports System.ComponentModel
Imports System.Globalization

'The namespace referenced from
'http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/f81b6caa-5fae-45c4-ad46-2240e84a5d7a

Namespace PropertyTreeClass

    <TypeConverter(GetType(AddressTypeTypeConverter))> _
    Public Class AddressType

        Private m_country As String
        <NotifyParentProperty(True), Description("國家"), RefreshProperties(RefreshProperties.Repaint)> _
        Public Property Country() As String
            Get
                Return m_country
            End Get

            Set(ByVal value As String)
                m_country = value
            End Set
        End Property

        Private m_city As String
        <NotifyParentProperty(True), Description("城市"), RefreshProperties(RefreshProperties.Repaint)> _
        Public Property City() As String
            Get
                Return m_city
            End Get

            Set(ByVal value As String)
                m_city = value
            End Set
        End Property
    End Class

    Public Class Person

        Public Sub New()
            homeAddressField = New AddressType()
        End Sub

        Private homeAddressField As AddressType

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
        Public Property HomeAddress() As AddressType
            Get
                Return Me.homeAddressField
            End Get

            Set(ByVal value As AddressType)
                Me.homeAddressField = value
            End Set
        End Property
    End Class

    Public Class AddressTypeTypeConverter
        Inherits TypeConverter

        Public Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
            'This method is used to shown information in the PropertyGrid.
            If destinationType Is GetType(String) Then
                Return (DirectCast(value, AddressType).Country & ",") + DirectCast(value, AddressType).City
            End If

            Return MyBase.ConvertTo(context, culture, value, destinationType)
        End Function

        Public Overrides Function GetProperties(ByVal context As ITypeDescriptorContext, ByVal value As Object, ByVal attributes As Attribute()) As PropertyDescriptorCollection
            Return TypeDescriptor.GetProperties(GetType(AddressType), attributes).Sort(New String() {"Country", "City"})
        End Function

        Public Overrides Function GetPropertiesSupported(ByVal context As ITypeDescriptorContext) As Boolean
            Return True
        End Function

    End Class

End Namespace




九月 15

先import 下面這2個namespace
Imports System.ComponentModel
Imports System.Reflection


<FlagsAttribute()> _
Public Enum Permissions

<Description("未設定")> _
None = 0

<Description("建立")> _
Create = 1

<Description("讀取")> _
Read = 2

<Description("更新")> _
Update = 4

<Description("刪除")> _
Delete = 8

<Description("所有功能")> _
All = Create Or Read Or Update Or Delete

End Enum

'要取得描述時使用下面的程式碼

Dim fi As FieldInfo = _
Permissions.Create.GetType().GetField(Permissions.Create.ToString())

Dim attributes As DescriptionAttribute() = _
CType(fi.GetCustomAttributes(GetType(DescriptionAttribute), False),  _
DescriptionAttribute())

'顯示取得的描述
Response.Write(attributes(0).Description)