C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: 冗長なコード


(過去ログ 135 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■79576 / inTopicNo.1)  冗長なコード
  
□投稿者/ なまごん (1回)-(2016/04/15(Fri) 16:40:51)

分類:[VB.NET/VB2005 以降] 

Form1にButtonを10個、テキストボックスを20個貼り付けています。
ボタンイベントをひとつのメソッドにまとめて、buttonの名前でselect文で分岐させるようにしたのですが、ボタンを増やす度に分岐も増やさないといけないところが冗長な感じがします。
これが仮にボタンが100個とかあった場合にはどのようなコードを書くのがベストなのでしょうか?
ご教示よろしくお願いします。
 
Private Sub Button_Click(ByVal Sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button4.Click, _
                Button5.Click, Button6.Click, Button7.Click, Button8.Click, Button9.Click, Button10.Click

        Select Case Sender.name
            Case "Button1"
                Test(Textbox1, Textbox11)
            Case "Button2"
                Test(Textbox2, Textbox12)
            Case "Button3"
                Test(Textbox3, Textbox13)
            Case "Button4"
                Test(Textbox4, Textbox14)
            Case "Button5"
                Test(TextBox5, Textbox15)
            Case "Button6"
                Test(Textbox6, Textbox16)
            Case "Button7"
                Test(Textbox7, Textbox17)
            Case "Button8"
                Test(Textbox8, Textbox18)
            Case "Button9"
                Test(Textbox9, Textbox19)
            Case "Button10"
                Test(Textbox10, Textbox20)
        End Select

    End Sub

引用返信 編集キー/
■79577 / inTopicNo.2)  Re[1]: 冗長なコード
□投稿者/ WebSurfer (893回)-(2016/04/15(Fri) 16:56:59)
No79576 (なまごん さん) に返信
> Form1にButtonを10個、テキストボックスを20個貼り付けています。
> ボタンイベントをひとつのメソッドにまとめて、buttonの名前でselect文で分岐させるようにしたのですが、ボタンを増やす度に分岐も増やさないといけないところが冗長な感じがします。
> これが仮にボタンが100個とかあった場合にはどのようなコードを書くのがベストなのでしょうか?

どうしても Button でなければならない理由があるのでしょうか?

ユーザーに選択させると言う目的なら、例えば(あくまで例えばです) ListBox を使うとか
でもう少しスマートにできそうな気がしますが・・・
引用返信 編集キー/
■79580 / inTopicNo.3)  Re[1]: 冗長なコード
□投稿者/ まりもん (1回)-(2016/04/15(Fri) 17:54:03)
あくまで全く同じ処理を実行する場合ですが、
TextBoxが2個、Buttonが1個、ButtonClickイベント、Value1プロパティ、Value2プロパティを持つUserControlを作成して

Private Sub UserControlButton_Click(ByVal Sender As System.Object, ByVal e As System.EventArgs) Handles UserControl1.ButtonClick, UserControl2.ButtonClick

    Test(Sender.Value1, Sender.Value2)

End Sub

みたいな感じはどうでしょう?

引用返信 編集キー/
■79582 / inTopicNo.4)  Re[2]: 冗長なコード
□投稿者/ ?????? (5回)-(2016/04/15(Fri) 21:41:57)
>>どうしても Button でなければならない理由があるのでしょうか?

シリアルポートが10個あり、それぞれに送信ボタンがあるのでこのようなコードになっています。
 

引用返信 編集キー/
■79583 / inTopicNo.5)  Re[2]: 冗長なコード
□投稿者/ ?????? (6回)-(2016/04/15(Fri) 21:48:57)
No79580 (まりもん さん) に返信
> あくまで全く同じ処理を実行する場合ですが、
> TextBoxが2個、Buttonが1個、ButtonClickイベント、Value1プロパティ、Value2プロパティを持つUserControlを作成して
>
> Private Sub UserControlButton_Click(ByVal Sender As System.Object, ByVal e As System.EventArgs) Handles UserControl1.ButtonClick, UserControl2.ButtonClick
>
> Test(Sender.Value1, Sender.Value2)
>
> End Sub
>
> みたいな感じはどうでしょう?
>


同じコントロールを複数使う場合はUserControlを使うと、このような簡素なコードになるのですね。
ありがとうございました。



解決済み
引用返信 編集キー/
■79584 / inTopicNo.6)  Re[3]: 冗長なコード
□投稿者/ Azulean (631回)-(2016/04/15(Fri) 23:27:58)
No79583 (?????? さん) に返信
> 同じコントロールを複数使う場合はUserControlを使うと、このような簡素なコードになるのですね。
> ありがとうございました。

あとは拡張プロパティかなぁ、あり得るとしたら。

たとえば、以下のようなクラスを作ってコンパイルした後、ButtonSet をデザイナで配置し、Button を選んだときに表示される追加プロパティに TextBox を割り当てていく。

Imports System.ComponentModel

<ProvideProperty("AttachedTextBox1", GetType(Button))> _
<ProvideProperty("AttachedTextBox2", GetType(Button))> _
Public Class ButtonSet
    Inherits System.ComponentModel.Component
    Implements System.ComponentModel.IExtenderProvider

    Private textBox1Table As New Dictionary(Of Button, TextBox)
    Private textBox2Table As New Dictionary(Of Button, TextBox)

    Public Function CanExtend(extendee As Object) As Boolean Implements System.ComponentModel.IExtenderProvider.CanExtend
        If TypeOf (extendee) Is Button Then
            Return True
        End If
        Return False
    End Function

    Public Function GetAttachedTextBox1(ByVal targetControl As Button) As TextBox
        Dim targetTextBox As TextBox
        If textBox1Table.TryGetValue(targetControl, targetTextBox) Then
            Return targetTextBox
        End If
        Return Nothing
    End Function

    Public Sub SetAttachedTextBox1(ByVal targetControl As Button, ByVal textBox As TextBox)
        textBox1Table(targetControl) = textBox
    End Sub

    Public Function GetAttachedTextBox2(ByVal targetControl As Button) As TextBox
        Dim targetTextBox As TextBox
        If textBox2Table.TryGetValue(targetControl, targetTextBox) Then
            Return targetTextBox
        End If
        Return Nothing
    End Function

    Public Sub SetAttachedTextBox2(ByVal targetControl As Button, ByVal textBox As TextBox)
        textBox2Table(targetControl) = textBox
    End Sub
End Class

イベントの方では以下のようにして取り出すとか。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click
    ButtonSet1.GetAttachedTextBox1(CType(sender, Button)).Text = "1 " & sender.Text
    ButtonSet1.GetAttachedTextBox2(CType(sender, Button)).Text = "2 " & sender.Text
End Sub

解決済み
引用返信 編集キー/
■79596 / inTopicNo.7)  Re[1]: 冗長なコード
□投稿者/ Mira (9回)-(2016/04/18(Mon) 16:33:59)
2016/04/18(Mon) 16:36:05 編集(投稿者)
No79576 (なまごん さん) に返信

こういう実装はいかがでしょうか?

        Dim ButtonIndex As Integer
        Integer.TryParse(DirectCast(sender, Button).Name.Substring("Button".Length), ButtonIndex)
        If ButtonIndex > 0 Then
            Dim TextBoxA As Control() = Me.Controls.Find("TextBox" + ButtonIndex.ToString, True)
            Dim TextBoxB As Control() = Me.Controls.Find("TextBox" + (ButtonIndex + 10).ToString, True)
            If TextBoxA.Length = 1 And TextBoxB.Length = 1 Then Test(TextBoxA(0), TextBoxB(0))
        End If

解決済み
引用返信 編集キー/
■79597 / inTopicNo.8)  Re[3]: 冗長なコード
□投稿者/ とくま (6回)-(2016/04/18(Mon) 17:58:01)
No79582 (?????? さん) に返信
> >>どうしても Button でなければならない理由があるのでしょうか?
>
> シリアルポートが10個あり、それぞれに送信ボタンがあるのでこのようなコードになっています。
>  
リスト1つと、送信ボタン1つで、選択リストに送信するようにすれば、
デザインの時点から冗長なコードにならない工夫ができるんじゃないの?
とかそういう事を言われているのでは?
解決済み
引用返信 編集キー/
■79599 / inTopicNo.9)  Re[4]: 冗長なコード
□投稿者/ なまごん (2回)-(2016/04/19(Tue) 18:48:25)
Azuleanさん、とくまさん、Miraさん
解決済みにしていたので、返信に気づかずすみませんでした。
質問がうまく伝わってないようなので、申し訳ありません。
質問の主旨は、同じコントロールが複数あったばあいに以下のようなコードにしないようにするには
どうすればいいのかを伺いたかったのです。

Private Sub Button_Click(ByVal Sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, _ 
                                       Button2.Click, Button3.Click,   〜〜〜〜〜〜〜〜〜, Button100.Click


        Select Case Sender.name
            Case "Button1"
                Test(Textbox1, Textbox100)
            Case "Button2"
                Test(Textbox2, Textbox102)
            Case "Button3"
                Test(Textbox3, Textbox103)
             :
             :
             :
             :
            Case "Button100"
                Test(Textbox100, Textbox200)

        End Select

end sub



まりもんに提示して頂いたとおり、UserControlを作成して複数のUserControlを動的に追加することにしました。
ただ、まりもんのコード
 >>Test(Sender.Value1, Sender.Value2)
ですと Sender にbutton名が入るので以下のようにしました。

   Dim uc As UserControl1 = DirectCast(Sender.Parent, UserControl1)
         Test(uc.Textbox1, uc.Textbox2)


実際のコードはこんな感じです。
UserControlにbutton1,Textbox1,Textbox2を配置しています。


Public Class Form1

    Private MyUserControl() As UserControl1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim i As Integer = 0
        Me.Width = 1000
        Me.Height = 400

        'UserControlを配列に10個用意
        Me.MyUserControl = New UserControl1(9) {}
        Me.SuspendLayout()

        'UserControlを動的に追加
        For i = 0 To Me.MyUserControl.Length - 1

            Me.MyUserControl(i) = New UserControl1
            Me.MyUserControl(i).Name = "UserControl" + i.ToString()
            Me.MyUserControl(i).Size = New Size(200, 200)

            If i < 5 Then
                Me.MyUserControl(i).Location = New Point(i * 200, 0)
            Else
                Me.MyUserControl(i).Location = New Point(i * 200 - 1000, 200)
            End If

            AddHandler Me.MyUserControl(i).Button1.Click, _
                AddressOf Me.Button1_Click
        Next i
        Me.Controls.AddRange(Me.MyUserControl)
        Me.ResumeLayout(False)

    End Sub

    Private Sub Button1_Click(ByVal Sender As Object, ByVal e As EventArgs)

        Dim uc As UserControl1 = DirectCast(Sender.Parent, UserControl1)
        Test(uc.Textbox1, uc.Textbox2)

    End Sub

    Private Sub Test(ByVal a As TextBox, ByVal b As TextBox)
        a.Text = "a"
        b.Text = "b"
    End Sub

End Class


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -