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

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

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

Re[7]: 空欄補充の重複を避けるには?


(過去ログ 132 を表示中)

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

■77829 / inTopicNo.1)  空欄補充の重複を避けるには?
  
□投稿者/ ごうき (5回)-(2015/11/24(Tue) 15:50:34)

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

vb2015です。

空欄補充のクイズみたいなものを作っています。

先に、空欄が埋まっている場合に、その上でマウスを放すと掴んでいるラベルを元の位置に戻したいです。

道具は、label1〜label6を使用しています。

以下のコードは、label4はlabel1〜label3まで埋めることができます。以下、label5、label6も同じ動作ができます。しかし、ラベル4〜ラベル6はラベル1に全て張ることができるので困っているのです。1つの空欄に1つのラベルを貼りたいです。

よろしくお願いします。

Public Class Form4
    Private Label_p4 As Point, Label_p5 As Point, Label_p6 As Point
    Private rect1 As Rectangle, rect2 As Rectangle, rect3 As Rectangle
    Private sender_Label4 As Label, sender_Label5 As Label, sender_Label6 As Label '移動中のLabel
    Private mp As Point 'マウスダウン時の座標

    Private Sub Form4_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Label_p4 = New Point(Label4.Left, Label4.Top) '初期位置を保管
        Label_p5 = New Point(Label5.Left, Label5.Top) '初期位置を保管
        Label_p6 = New Point(Label6.Left, Label6.Top) '初期位置を保管
        rect1 = New Rectangle(Label1.Left, Label1.Top, Label1.Width, Label1.Height)
        rect2 = New Rectangle(Label2.Left, Label2.Top, Label2.Width, Label2.Height)
        rect3 = New Rectangle(Label3.Left, Label3.Top, Label3.Width, Label3.Height)
        Me.Controls.Add(Label4)
        AddHandler Label4.MouseDown, AddressOf Label4_MouseDown
        AddHandler Label4.MouseMove, AddressOf Label4_MouseMove
        AddHandler Label4.MouseUp, AddressOf Label4_MouseUp
        Me.Controls.Add(Label5)
        AddHandler Label5.MouseDown, AddressOf Label5_MouseDown
        AddHandler Label5.MouseMove, AddressOf Label5_MouseMove
        AddHandler Label5.MouseUp, AddressOf Label5_MouseUp
        Me.Controls.Add(Label6)
        AddHandler Label6.MouseDown, AddressOf Label6_MouseDown
        AddHandler Label6.MouseMove, AddressOf Label6_MouseMove
        AddHandler Label6.MouseUp, AddressOf Label6_MouseUp
    End Sub

    Private Sub Label4_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then '左クリック
            mp = Me.PointToClient(Cursor.Position) 'マウスを押した位置の座標を取得
            sender_Label4 = DirectCast(sender, Label) '移動させるlabel
            sender_Label4.BringToFront() '最前面へ移動
            sender_Label4.BackColor = Color.Pink
            sender_Label4.Cursor = Cursors.Hand 'ポインターを変更したければ
        End If
    End Sub

    Public Sub Label4_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then '左クリック
            Dim new_mp As Point = Me.PointToClient(Cursor.Position) 'マウスの最新座標
            If rect1.Contains(New Point(new_mp.X, new_mp.Y)) Then
                'マウスが目的のLabelの領域内に入ったら吸着させる
                sender_Label4.Location = New Point(rect1.X, rect1.Y)
            ElseIf rect2.Contains(New Point(new_mp.X, new_mp.Y)) Then
                'マウスが目的のLabelの領域内に入ったら吸着させる
                sender_Label4.Location = New Point(rect2.X, rect2.Y)
            ElseIf rect3.Contains(New Point(new_mp.X, new_mp.Y)) Then
                'マウスが目的のLabelの領域内に入ったら吸着させる
                sender_Label4.Location = New Point(rect3.X, rect3.Y)
            Else
                'マウスが目的のLabelの領域外であれば自由に移動
                sender_Label4.Left += (new_mp.X - mp.X)
                sender_Label4.Top += (new_mp.Y - mp.Y)
            End If
            mp = new_mp 'マウス座標を更新
        End If
    End Sub

    Private Sub Label4_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then '左クリック

            'マウスが目的の領域外の時は移動中のLabelを元の位置に戻す
            If Not (rect1.Contains(New Point(mp.X, mp.Y)) Or rect2.Contains(New Point(mp.X, mp.Y)) Or rect3.Contains(New Point(mp.X, mp.Y))) Then
                sender_Label4.Location = New Point(Label_p4.X, Label_p4.Y)
            End If
            sender_Label4.BackColor = Color.PowderBlue
            sender_Label4.Cursor = Cursors.Default 'ポインターを変更したければ
        End If
    End Sub

    Private Sub label5_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then '左クリック
            mp = Me.PointToClient(Cursor.Position) 'マウスを押した位置の座標を取得
            sender_label5 = DirectCast(sender, Label) '移動させるlabel
            sender_label5.BringToFront() '最前面へ移動
            sender_label5.BackColor = Color.Pink
            sender_label5.Cursor = Cursors.Hand 'ポインターを変更したければ
        End If
    End Sub

    Public Sub label5_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then '左クリック
            Dim new_mp As Point = Me.PointToClient(Cursor.Position) 'マウスの最新座標
            If rect1.Contains(New Point(new_mp.X, new_mp.Y)) Then
                'マウスが目的のLabelの領域内に入ったら吸着させる
                sender_Label5.Location = New Point(rect1.X, rect1.Y)
            ElseIf rect2.Contains(New Point(new_mp.X, new_mp.Y)) Then
                'マウスが目的のLabelの領域内に入ったら吸着させる
                sender_Label5.Location = New Point(rect2.X, rect2.Y)
            ElseIf rect3.Contains(New Point(new_mp.X, new_mp.Y)) Then
                'マウスが目的のLabelの領域内に入ったら吸着させる
                sender_Label5.Location = New Point(rect3.X, rect3.Y)
            Else
                'マウスが目的のLabelの領域外であれば自由に移動
                sender_Label5.Left += (new_mp.X - mp.X)
                sender_label5.Top += (new_mp.Y - mp.Y)
            End If
            mp = new_mp 'マウス座標を更新
        End If
    End Sub

    Private Sub label5_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then '左クリック

            'マウスが目的の領域外の時は移動中のLabelを元の位置に戻す
            If Not (rect1.Contains(New Point(mp.X, mp.Y)) Or rect2.Contains(New Point(mp.X, mp.Y)) Or rect3.Contains(New Point(mp.X, mp.Y))) Then
                sender_Label5.Location = New Point(Label_p5.X, Label_p5.Y)
            End If
            sender_Label5.BackColor = Color.PowderBlue
            sender_label5.Cursor = Cursors.Default 'ポインターを変更したければ
        End If
    End Sub

    Private Sub label6_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then '左クリック
            mp = Me.PointToClient(Cursor.Position) 'マウスを押した位置の座標を取得
            sender_Label6 = DirectCast(sender, Label) '移動させるlabel
            sender_Label6.BringToFront() '最前面へ移動
            sender_Label6.BackColor = Color.Pink
            sender_Label6.Cursor = Cursors.Hand 'ポインターを変更したければ
        End If
    End Sub

    Public Sub label6_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then '左クリック
            Dim new_mp As Point = Me.PointToClient(Cursor.Position) 'マウスの最新座標
            If rect1.Contains(New Point(new_mp.X, new_mp.Y)) Then
                'マウスが目的のLabelの領域内に入ったら吸着させる
                sender_Label6.Location = New Point(rect1.X, rect1.Y)
            ElseIf rect2.Contains(New Point(new_mp.X, new_mp.Y)) Then
                'マウスが目的のLabelの領域内に入ったら吸着させる
                sender_Label6.Location = New Point(rect2.X, rect2.Y)
            ElseIf rect3.Contains(New Point(new_mp.X, new_mp.Y)) Then
                'マウスが目的のLabelの領域内に入ったら吸着させる
                sender_Label6.Location = New Point(rect3.X, rect3.Y)
            Else
                'マウスが目的のLabelの領域外であれば自由に移動
                sender_Label6.Left += (new_mp.X - mp.X)
                sender_Label6.Top += (new_mp.Y - mp.Y)
            End If
            mp = new_mp 'マウス座標を更新
        End If
    End Sub

    Private Sub label6_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If e.Button = MouseButtons.Left Then '左クリック

            'マウスが目的の領域外の時は移動中のLabelを元の位置に戻す
            If Not (rect1.Contains(New Point(mp.X, mp.Y)) Or rect2.Contains(New Point(mp.X, mp.Y)) Or rect3.Contains(New Point(mp.X, mp.Y))) Then
                sender_Label6.Location = New Point(Label_p6.X, Label_p6.Y)
            End If
            sender_Label6.BackColor = Color.PowderBlue
            sender_Label6.Cursor = Cursors.Default 'ポインターを変更したければ
        End If
    End Sub
End Class

引用返信 編集キー/
■77837 / inTopicNo.2)  Re[1]: 空欄補充の重複を避けるには?
□投稿者/ Jitta (162回)-(2015/11/24(Tue) 20:39:42)
No77829 (ごうき さん) に返信
 これ、ラベルが6個くらいならまだいいけど、ラベルが20個とかになっても、このスタイルで行きます?
VB はよくわかんないんだけど...

Dim labels As List[Label] = New List[Label]

とかでリストとして宣言して、

labels.Add(Label1)
labels.Add(Label2)

のようにリストに登録すると、

For Each l As Label In labels
  AddHandler l.MouseDown, AddressOf LabelMouseDown
End For

のような感じで、For 文でぶん回して使うことができます。
ハンドラーメソッドでは sender を使えば、
いちいち Label? でコーディングする必要はなく、
コード量が減って見通しが良くなるし、
同じ(様な)コードを大量生産しないので修正漏れを防げますよ。

> Private Label_p4 As Point, Label_p5 As Point, Label_p6 As Point
> Private rect1 As Rectangle, rect2 As Rectangle, rect3 As Rectangle
> Private sender_Label4 As Label, sender_Label5 As Label, sender_Label6 As Label '移動中のLabel

クラス変数として宣言されていますが、同時に動かすことができるラベルは1つだけですよね?
であれば、「今動かしているラベル」だけ覚えるようにすれば良いです。
また、変数を参照できるエリアはできるだけ狭くし、宣言する変数は必要最小限にしましょう。
プログラムを実行するのはコンピュータで、コンピュータは忘れることはありません。
しかし、プログラムをメンテナンスするのは人間です。
人間は忘れます。
ですから、人間が覚えるものは少なくする方が、メンテナンスしやすくなります。

引用返信 編集キー/
■77841 / inTopicNo.3)  Re[2]: 空欄補充の重複を避けるには?
□投稿者/ ごうき (6回)-(2015/11/24(Tue) 20:49:00)
No77837 (Jitta さん) に返信
> ■No77829 (ごうき さん) に返信
>  これ、ラベルが6個くらいならまだいいけど、ラベルが20個とかになっても、このスタイルで行きます?
> VB はよくわかんないんだけど...
>
> Dim labels As List[Label] = New List[Label]
>
> とかでリストとして宣言して、
>
> labels.Add(Label1)
> labels.Add(Label2)
>
> のようにリストに登録すると、
>
> For Each l As Label In labels
>   AddHandler l.MouseDown, AddressOf LabelMouseDown
> End For
>
> のような感じで、For 文でぶん回して使うことができます。
> ハンドラーメソッドでは sender を使えば、
> いちいち Label? でコーディングする必要はなく、
> コード量が減って見通しが良くなるし、
> 同じ(様な)コードを大量生産しないので修正漏れを防げますよ。
>
>>Private Label_p4 As Point, Label_p5 As Point, Label_p6 As Point
>>Private rect1 As Rectangle, rect2 As Rectangle, rect3 As Rectangle
>>Private sender_Label4 As Label, sender_Label5 As Label, sender_Label6 As Label '移動中のLabel
>
> クラス変数として宣言されていますが、同時に動かすことができるラベルは1つだけですよね?
> であれば、「今動かしているラベル」だけ覚えるようにすれば良いです。
> また、変数を参照できるエリアはできるだけ狭くし、宣言する変数は必要最小限にしましょう。
> プログラムを実行するのはコンピュータで、コンピュータは忘れることはありません。
> しかし、プログラムをメンテナンスするのは人間です。
> 人間は忘れます。
> ですから、人間が覚えるものは少なくする方が、メンテナンスしやすくなります。

回答ありがとうございます。
<これ、ラベルが6個くらいならまだいいけど、ラベルが20個とかになっても、このスタイルで行きます?

動かすラベルは最高4つです。全て同時には動かしません。マウスで1つ1つ動かします。
うまくまとめる方法を勉強中なのですが、まずは、全部書いてしまえ・・・といった感じになっています。



>
引用返信 編集キー/
■77855 / inTopicNo.4)  Re[3]: 空欄補充の重複を避けるには?
□投稿者/ ななしん (2回)-(2015/11/25(Wed) 13:52:29)
クイズなんですから、どの欄に何が埋められたか判断しないといけないわけですよね
ラベルのMouseUpイベント時に、空欄を埋める位置なら何かしら情報を覚えておいて
空欄なのか、すでに他のものが埋められているのか判断すればよろしいかと
引用返信 編集キー/
■77857 / inTopicNo.5)  Re[4]: 空欄補充の重複を避けるには?
□投稿者/ ごうき (9回)-(2015/11/25(Wed) 14:21:46)
No77855 (ななしん さん) に返信
> クイズなんですから、どの欄に何が埋められたか判断しないといけないわけですよね
> ラベルのMouseUpイベント時に、空欄を埋める位置なら何かしら情報を覚えておいて
> 空欄なのか、すでに他のものが埋められているのか判断すればよろしいかと

回答ありがとうございます

例えば、どのような書き方があるでしょうか・・・ラベル移動など初めての試みで悪戦苦闘しております。
コードのヒントなどありませんでしょうか

よろしくお願いします。
引用返信 編集キー/
■77858 / inTopicNo.6)  Re[5]: 空欄補充の重複を避けるには?
□投稿者/ ごうき (10回)-(2015/11/25(Wed) 14:21:55)
No77857 (ごうき さん) に返信
> ■No77855 (ななしん さん) に返信
>>クイズなんですから、どの欄に何が埋められたか判断しないといけないわけですよね
>>ラベルのMouseUpイベント時に、空欄を埋める位置なら何かしら情報を覚えておいて
>>空欄なのか、すでに他のものが埋められているのか判断すればよろしいかと
>
> 回答ありがとうございます
>
> 例えば、どのような書き方があるでしょうか・・・ラベル移動など初めての試みで悪戦苦闘しております。
> コードのヒントなどありませんでしょうか
>
> よろしくお願いします。
引用返信 編集キー/
■77859 / inTopicNo.7)  Re[5]: 空欄補充の重複を避けるには?
□投稿者/ ななしん (3回)-(2015/11/25(Wed) 16:29:41)
別にラベルの移動とは関係ないと思いますよ
現在の空欄の状態を覚える為の変数を用意して、どれを入れたのかMouseUpで覚えさせればいいだけです。

Dim Blank1 As Integer     '空欄に何が入っているか判断するための変数 0は空欄、1〜は答えの番号

答えを移動した時のMouseUpで下記のような判断をすればいいかと
空欄1に重ねた時の判断
If Blank1 = 0 Then
    '空欄なのでそのまま格納
    Blank1 = 1
Else
    '前に何か入っているのでその時の処理
    '前に入っている答えを初期位置に戻すなり今回動かしていたものを戻すなり
End If

空欄の判断の変数を配列にするなり、いろいろあるとは思いますが、基本は変わらないかと

引用返信 編集キー/
■77861 / inTopicNo.8)  Re[6]: 空欄補充の重複を避けるには?
□投稿者/ ごうき (11回)-(2015/11/25(Wed) 23:36:07)
No77859 (ななしん さん) に返信
> 別にラベルの移動とは関係ないと思いますよ
> 現在の空欄の状態を覚える為の変数を用意して、どれを入れたのかMouseUpで覚えさせればいいだけです。
>
> Dim Blank1 As Integer '空欄に何が入っているか判断するための変数 0は空欄、1〜は答えの番号
>
> 答えを移動した時のMouseUpで下記のような判断をすればいいかと
> 空欄1に重ねた時の判断
> If Blank1 = 0 Then
> '空欄なのでそのまま格納
> Blank1 = 1
> Else
> '前に何か入っているのでその時の処理
> '前に入っている答えを初期位置に戻すなり今回動かしていたものを戻すなり
> End If
>
> 空欄の判断の変数を配列にするなり、いろいろあるとは思いますが、基本は変わらないかと

ヒントを参考に再現することができました。
ありがとうございます。


解決済み
引用返信 編集キー/
■77862 / inTopicNo.9)  Re[7]: 空欄補充の重複を避けるには?
□投稿者/ ぽぴ王子 (34回)-(2015/11/26(Thu) 09:10:13)
ぽぴ王子 さんの Web サイト
2015/11/26(Thu) 09:10:52 編集(投稿者)

解決済みを外してしまっていたので編集…

No77861 (ごうき さん) に返信
回答ではないのですが。(もう解決済みですし)

> ヒントを参考に再現することができました。
> ありがとうございます。

「できました」はそれでかまわないわけですが、できれば「ここをこういう風にしてできました」
と書いておいていただけると、後から同じようなことでつまづいた人も、もしかすると回答してくれた
方も安心するのではないかしら?と思います。

自分一人で考えているぶんには「わからない」→「できた!」で完結する話なのですけど、他人を
巻き込んで、しかも掲示板上の話なので見ているかたも(回答はしていないとしても)まきこんで
しまっているのかなあと思うのです。なので、解決した場合は解決策を書いておいていただけると
助かります。

見ているだけの私も安心しますし、最初に書いたように同じ原因でつまづいた方が見なおしてみて
質問する前に解決できるようならそれはそれでいいことだと思います。

今度から、解決した際はどんなふうに解決したのか書いてみてください。(強制ではありません)
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -