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

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

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

Re[9]: 子フォームの選択を親フォームにて


(過去ログ 135 を表示中)

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

■79501 / inTopicNo.1)  子フォームの選択を親フォームにて
  
□投稿者/ 初心者 (52回)-(2016/04/09(Sat) 23:36:42)

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

へんてこなプログラムですが動作確認のものです。
よろしくお願いします。

普通は子フォームのForm2にて動作1・動作2の選択をするのでしょうが、
それを親フォームのForm1にて出来ないものかと思っています。

例えば、Form1の動作1をクリックすればForm2のLabel1に日時の表示がされます。
そこで次にForm1の動作2をクリックです。
さすれば新しくForm2が開きますが、そうではなく最初に開いたForm2をそのまま使いたいのです。
即ち、そのForm2には最初のLabel1と共にLabel2にも日時が表示がされることになります。
もちろんLabel1の時計は一度も止まらずに。

Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.IsMdiContainer = True   'このフォームを MDI コンテナとして設定
    End Sub

    Private Sub 動作1ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 動作1ToolStripMenuItem.Click
        Dim frmchild As New Form2
        frmchild.MdiParent = Me
        frmchild.Tag = "動作1"
        frmchild.Show()
    End Sub

    Private Sub 動作2ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 動作2ToolStripMenuItem.Click
        Dim frmchild As New Form2
        frmchild.MdiParent = Me
        frmchild.Tag = "動作2"
        frmchild.Show()
    End Sub
End Class

Public Class Form2
    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Start()    'タイマー開始
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If Me.Tag = "動作1" Then
            Label1.Text = DateTime.Now
        End If
        If Me.Tag = "動作2" Then
            Label2.Text = DateTime.Now
        End If
    End Sub
End Class

引用返信 編集キー/
■79502 / inTopicNo.2)  Re[1]: 子フォームの選択を親フォームにて
□投稿者/ WebSurfer (888回)-(2016/04/10(Sun) 00:45:07)
No79501 (初心者 さん) に返信

あなたは、

http://bbs.wankuma.com/index.cgi?mode=al2&namber=79448

の初心者さんと同じ人ですか?
引用返信 編集キー/
■79503 / inTopicNo.3)  Re[2]: 子フォームの選択を親フォームにて
□投稿者/ daive (99回)-(2016/04/10(Sun) 02:53:07)
2016/04/10(Sun) 03:07:52 編集(投稿者)
>普通は子フォームのForm2にて動作1・動作2の選択をするのでしょうが、
>それを親フォームのForm1にて出来ないものかと思っています。
>例えば、Form1の動作1をクリックすればForm2のLabel1に日時の表示がされます。
>そこで次にForm1の動作2をクリックです。
>さすれば新しくForm2が開きますが、そうではなく最初に開いたForm2をそのまま使いたいのです。
>即ち、そのForm2には最初のLabel1と共にLabel2にも日時が表示がされることになります。
>もちろんLabel1の時計は一度も止まらずに。
プログラムは、理窟で動作します。
ですので、先ず行うべきは、
1.要求、要件を箇条書きで、誰にでも判るように、表してください。
  現状の掲示は、一目で判るようには、書かれていません。
2. 初心者 さんという、だれだか判らない名称でなく(この名称は過去から使いまわされています。)
  誰だか特定できる、ハンドルネームにしてください。
  他には、名無し、通りすがり、未記入など使いまわされている様子な名前もあります。
3.先の質問の続きであれば、その質問のURLを掲示してください。
  その方が親切ですし、後から見直す時に、質問を探し廻らないで済みます。
  定型で、OS、開発環境を記入するようにしてください。

>もちろんLabel1の時計は一度も止まらずに。
掲示コードでは、Label1.Text / Label2.Text は、Tag の内容で
表示したり、しなかったりを、していますよね?
dobonさんのコードを拝借しての、こんな感じかなぁコード

Public Class Form1

    ''' <summary>
    ''' 初期化時に、フォームを MDI コンテナとして設定
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        Me.IsMdiContainer = True
    End Sub

    ''' <summary>
    ''' 動作1:一意の子フォームとして開く、TAG:動作1
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub btt_動作1_Click(sender As Object, e As EventArgs) Handles btt_動作1.Click
        Form2.Instance.MdiParent = Me
        Form2.Instance.Tag = "動作1"
        Form2.Instance.Show()
        Form2.Instance.Timer1.Enabled = True
    End Sub

    ''' <summary>
    ''' 動作2:一意の子フォームとして開く、TAG:動作2
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub btt_動作2_Click(sender As Object, e As EventArgs) Handles btt_動作2.Click
        Form2.Instance.MdiParent = Me
        Form2.Instance.Tag = "動作2"
        Form2.Instance.Show()
        Form2.Instance.Timer1.Enabled = True
    End Sub

End Class

Public Class Form2
    '*********************************************************
    'フォームが一つしか表示されないようにする
    'http://dobon.net/vb/dotnet/form/singleform.html
    '*********************************************************

    ''' <summary>
    ''' ただ一つのフォームのインスタンスを保持するフィールド
    ''' </summary>
    Private Shared _instance As Form2


    ''' <summary>
    ''' ただ一つのフォームにアクセスするためのプロパティ
    ''' </summary>
    ''' <returns></returns>
    Public Shared ReadOnly Property Instance() As Form2
        Get
            '_instanceがnullまたは破棄されているときは、
            '新しくインスタンスを作成する
            If _instance Is Nothing OrElse _instance.IsDisposed Then
                _instance = New Form2
            End If
            Return _instance
        End Get
    End Property

    ''' <summary>
    ''' タイマーで、Label1 / Label2 へ表示分け
    ''' 好みはあるにしても、似た事ズラズラでは、敢えてマルチステートメント
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

        Select Case Me.Tag
            Case "動作1" : Label1.Text = DateTime.Now.ToString("yyyy-mm-dd HH:mm:ss")
            Case "動作2" : Label2.Text = DateTime.Now.ToString("yyyy-mm-dd HH:mm:ss")
        End Select

    End Sub
End Class

引用返信 編集キー/
■79509 / inTopicNo.4)  Re[3]: 子フォームの選択を親フォームにて
□投稿者/ 初心者 (53回)-(2016/04/10(Sun) 20:18:32)
No79503 (daive さん) に返信

ありがとうございます。

> 1.要求、要件を箇条書きで、誰にでも判るように、表してください。
>   現状の掲示は、一目で判るようには、書かれていません。
何分、初心者ゆえの悲しさ
判るようには書いた積もりなのですが申し訳ないです。

> 2. 初心者 さんという、だれだか判らない名称でなく(この名称は過去から使いまわされています。)
>   誰だか特定できる、ハンドルネームにしてください。
>   他には、名無し、通りすがり、未記入など使いまわされている様子な名前もあります。
初心者ですので他の方と同様に初心者とはしましたが、ハンドルネームで誰だかの特定をする必要があるのでしたら以降改めます。

> 3.先の質問の続きであれば、その質問のURLを掲示してください。
>   その方が親切ですし、後から見直す時に、質問を探し廻らないで済みます。
>   定型で、OS、開発環境を記入するようにしてください。
これは単独の質問です。続きではありません。
OSはWindows 7
開発環境は
> 分類:[VB.NET/VB2005 以降]
とはまた違うのでしょうか?

> >もちろんLabel1の時計は一度も止まらずに。
> 掲示コードでは、Label1.Text / Label2.Text は、Tag の内容で
> 表示したり、しなかったりを、していますよね?
> dobonさんのコードを拝借しての、こんな感じかなぁコード

新しいフォームは開かなくはなりましたが
> >もちろんLabel1の時計は一度も止まらずに。
は、やはり無理なのでしょうか?
動作1をクリック後に動作2をクリックすればLabel1の表示は止まってしまいます。
これが一番の問題(課題)でもあるのです。

引用返信 編集キー/
■79511 / inTopicNo.5)  Re[4]: 子フォームの選択を親フォームにて
□投稿者/ daive (102回)-(2016/04/11(Mon) 09:02:07)
No79509 (初心者 さん) に返信
>は、やはり無理なのでしょうか?
>動作1をクリック後に動作2をクリックすればLabel1の表示は止まってしまいます。
>これが一番の問題(課題)でもあるのです。
それは、

 Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If Me.Tag = "動作1" Then
            Label1.Text = DateTime.Now
        End If
        If Me.Tag = "動作2" Then
            Label2.Text = DateTime.Now
        End If
    End Sub
と、条件判断しているからで、
Label1 を常時表示であれば、条件文を取れば良いのですし、
 Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Label1.Text = DateTime.Now
        If Me.Tag = "動作2" Then
            Label2.Text = DateTime.Now
        End If
    End Sub
とすれば、よいですし、
Label1 / 2 両方であれば、
 Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Label1.Text = DateTime.Now
        Label2.Text = DateTime.Now
    End Sub
’
>初心者ですので他の方と同様に初心者とはしましたが、ハンドルネームで誰だかの特定をする必要があるのでしたら以降改めます。
是非とも、改めてください。他の方と被らない名称としてください。
特定の名称とする事により、質問の内容に信頼性が生まれ、
回答者の方にも、回答の一貫性を考慮する余地が生まれます。
’
>開発環境は
>> 分類:[VB.NET/VB2005 以降]
>とはまた違うのでしょうか?
使っている、VB.NET は、何ですかとの問いです。
 VB.NETは、2002 / 2003 / 2005 / 2008 / 2010 / 2012 / 2013 / 2015 とバージョンがあり、
 エディションは、 VB.NET 2005 以後は、Express / Professional / Enterprise 等
 VB.NET 2013 以後は、Community が登場して、各々違いが有ったりします。
 OS、開発ツールのバージョン、エディションは、回答者が追試する上での、必要情報です。

引用返信 編集キー/
■79512 / inTopicNo.6)  Re[5]: 子フォームの選択を親フォームにて
□投稿者/ 初心者 (54回)-(2016/04/11(Mon) 11:59:29)
No79511 (daive さん) に返信

ありがとうございます。

動作1または動作2のどちらかをクリックするこにより初めて開始としたいのです。
もちろん一旦開始をした限りは継続ですが。
いずれにしてもこのままでは難しいようですのでもう少し考えてみます。
ちなみにVB2012です。

引用返信 編集キー/
■79513 / inTopicNo.7)  Re[6]: 子フォームの選択を親フォームにて
□投稿者/ Jitta (188回)-(2016/04/11(Mon) 13:32:50)
ヒント:フラグ
引用返信 編集キー/
■79533 / inTopicNo.8)  Re[7]: 子フォームの選択を親フォームにて
□投稿者/ daive (103回)-(2016/04/12(Tue) 10:39:43)
質問者さんの掲示が無い部分は、
たぶん、こう云う事のはずです。
’
〔動作想定例〕
Aパターン:初回の、【動作1】または、【動作2】の時は、以下の様に表示します。
      1.Label1.Text の更新条件
      2.Label2.Text の更新条件

Bパターン:初回の、【動作1】の時は、以下の様に表示します。
      1.Label1.Text の更新条件
      2.Label2.Text の更新条件

Cパターン:初回の、【動作2】の時は、以下の様に表示します。
      1.Label1.Text の更新条件
      2.Label2.Text の更新条件
’
2回目以後の、【動作1】の時は、以下の様に表示します。
1.Label1.Text の更新条件
2.Label2.Text の更新条件

2回目以後の、【動作2】の時は、以下の様に表示します。
1.Label1.Text の更新条件
2.Label2.Text の更新条件


引用返信 編集キー/
■79546 / inTopicNo.9)  Re[8]: 子フォームの選択を親フォームにて
□投稿者/ 初心者 (55回)-(2016/04/13(Wed) 15:07:01)
色々ありがとうございました。

先にも述べましたがこのままでは難しいようです。
それに実際にはもっと複雑でサンプルでは動いてもその部分ですらエラーが出てしまう始末。
これ以上はご迷惑を掛けます。
一旦解決とし他の方法も模索してみることにします。

解決済み
引用返信 編集キー/
■79547 / inTopicNo.10)  Re[9]: 子フォームの選択を親フォームにて
□投稿者/ Jitta (189回)-(2016/04/13(Wed) 16:47:12)
2016/04/13(Wed) 21:19:21 編集(投稿者)
> ハンドルネームで誰だかの特定をする必要があるのでしたら以降改めます。
 「誰かを特定する」という意味では、必要ありません。
私たちは、仕事をするときに、守秘義務を負います。
あることについて尋ね、解決しました。次のことについて尋ね、解決しました。
これを繰り返していくと、何を作っているのか、わかることがあります。
(もちろん、最初の質問だけでもわかることがあります。)
そうすると、守秘義務に反するかもしれません。
ですから、ある質問と、次の質問で、ハンドルを変えるのは「あり」です。
ただし、次の質問では、「ある質問」をしなかったとして、最初から解説しなければなりません。
よって、これが仕事に関係することなら、「こういう場所で、この内容で質問したい」と、上司に許可を求めておく方が安全です。
会社が隠したいものをあなたが知っている(「判断できる」ではない)、というなら、かまいませんが。


> 何分、初心者ゆえの悲しさ
> 判るようには書いた積もりなのですが申し訳ないです。
 それはおかしいです。
確かに、「プログラムを作ること」については、初心者かもしれません。
しかし、「質問すること/尋ねること/学ぶこと」については、初心者ではないはずです。

 プログラムとは、なんでしょうか。
音楽会や運動会の前に、「その会で何を、どの様な順番でするか」を書いたものをもらうのではないでしょうか。
その「することを順番を書いたもの」を「プログラム」といわないでしょうか。
我々が作るのは、「コンピュータに実現して欲しいことを、それが実現できる順番に、コンピュータにわかる言語で書いたもの」です。
そうすると、プログラムを作ること、すなわち「何かをするために、どんなことを、どんな順番にしなければならないかを考えること」も、初心者ではないはずです。

 もっとも、人間は、その他の情報をつなぎ合わせて、語られなかったことを推測します。
コンピュータは、推測しません。
そのため、「これくらいでわかるだろう」「察してくれるだろう」が通用しません。
この、「察してくれるだろう」を排除することについては、初心者だと言えるでしょう。
そして、「語られなかったことを推測できない」のは、こういうネットの向こうの人に質問するときも同じです。
人間が推測するのは、情報があるからです。
周りにあるもの、表情、イントネーションといった情報から、何が重要かを推測します。
ということは、プログラムを作ることで悩むことと、ネットの向こうに質問しても「思う様な回答が得られない」は、ほぼ同じと言えます。
つまり、プログラム作りに悩んだからといって、プログラムを作るのと同じくらい難しいネットの向こうの人に尋ねるということをしているのは、私はおかしいと思います。


> 例えば、Form1の動作1をクリックすればForm2のLabel1に日時の表示がされます。
> そこで次にForm1の動作2をクリックです。
> さすれば新しくForm2が開きますが、そうではなく最初に開いたForm2をそのまま使いたいのです。
> 即ち、そのForm2には最初のLabel1と共にLabel2にも日時が表示がされることになります。
> もちろんLabel1の時計は一度も止まらずに。

* Form1 に、"動作1" と "動作2" というメニューがある。
* "動作1" は、Form2 を表示し、Form2 上の Label1 に、現在日時を表示する。
* "動作2" は、Form2 を表示し、Form2 上の Label2 に、現在日時を表示する。
("動作1" と "動作2" の違いは、現在日時の表示先である。)
* "動作1" 選択後に "動作2" を選択した、あるいはその逆の場合、Form2 の表示は1つのみとする。
* 現在日時は、リアルタイムで更新する。

 「どうしたら、どうする」の様に、短文で並べる方が伝わりやすいです。
結局、コンピュータが理解できるのはこういう短文です。
我々は小学校からずっと、「作文」をさせられてきました。
いかに言葉を修飾して、美しい文章を書くかを習ってきました。
これは、コンピュータ向けのプログラム コードを書くということとは、真反対のことであると言えるでしょう。
しかし、ビジネス文書、特に仕様や報告では、このような短文が好まれます。

 しかし、なんで、VB 使うかなぁ。
ソフトウェア開発者にとって、ソフトウェア開発者以外のプログラムを作らなければならない人向けに設計された VB って、使いにくいと思うんだけどなぁ。

Public Class Form1

    Private f2 As Form2

    Private Sub 動作1ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles 動作1ToolStripMenuItem.Click
        Dim flag As Integer = CTypeDynamic(Of Integer)(Me.f2.Tag)
        flag = (flag Or 1)
        Me.f2.Tag = flag
        Me.f2.Show()
    End Sub

    Private Sub 動作2ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles 動作2ToolStripMenuItem.Click
        Dim flag As Integer = CTypeDynamic(Of Integer)(Me.f2.Tag)
        flag = (flag Or 2)
        Me.f2.Tag = flag
        Me.f2.Show()
    End Sub

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Me.f2 = New Form2
        Me.f2.Tag = 0
    End Sub
End Class

Public Class Form2

    Private Sub Form2_Shown(sender As System.Object, e As System.EventArgs) Handles MyBase.Shown
        Me.Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
        Dim flag As Integer = CTypeDynamic(Of Integer)(Me.Tag)
        Dim now As String = DateTime.Now.ToString
        If ((flag And 1) > 0) Then Label1.Text = String.Format("現在時刻1:{0}", now)
        If ((flag And 2) > 0) Then Label2.Text = String.Format("現在時刻2:{0}", now)
    End Sub

    Private Sub Form2_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        e.Cancel = True
        Me.Tag = 0
        Me.Label1.Text = String.Empty
        Me.Label2.Text = String.Empty
        Me.Hide()
    End Sub
End Class

通常、ON/OFF の状態を表すことを、フラグといいます。
フラグは、Boolean 型で True / False として表現することが多いです。
しかし、ON を 1、OFF を 0 として、数値型で表現することもできます。

解決策1:
今回、"動作1" と "動作2" という2つの状態を表すので、Form2 に Public な Boolean 型の2つのフラグを作れば良いでしょう。

解決策2:
1 or 0 なので、1ビットの幅があれば事足ります。
ですから、Int32 型を使うなら、1つの変数で32個の状態を表現することができます。
上記コードでは Tag に Integer 型を設定します。
最上位を1ビット目として、1は32ビット目、2は31ビット目ですから、ビットごとに別々の意味を持たせたフラグを設定したことになります。

解決策3:
解決策2では、1や2という数字の意味を、人が覚えておかなければなりません。
それは、結構しんどいことです。
そこで、列挙体に FlagsAttribute を付けてフラグとして扱います。

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


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

このトピックに書きこむ

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

管理者用

- Child Tree -