質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.46%

  • VB.NET

    698questions

    Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

  • Visual Studio 2010

    111questions

    Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

  • Windows Forms

    62questions

    Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

  • .NET Framework 4.0

    51questions

    Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

VisualStudioでデバッグ中にプロパティの値が変化する

解決済

回答 1

投稿 2017/10/28 12:42 ・編集 2017/10/28 13:41

  • 評価
  • クリップ 0
  • VIEW 114

arisuke

score 1

お世話になります。

前提

現在、WinFormアプリをVB.NETで作成しています。
またボタンをクリックすることでMonthCalendarのサイズに合わせたフォームを表示するフォームを作成しています。
このMonthCalendarのサイズに合わせたフォームを作成するときに以下の問題が発生しました。

発生している問題

デバッグモードでインスタンスのプロパティを見ることで、プロパティの値が変化する。

該当のソースコード

簡略化したソースコードを載せておきます。

Public Class Form
    Public Sub New()
        InitializeComponent()

        Dim button As New Button()
        AddHandler button.Click, AddressOf Button_Click
        Me.Controls.Add(button)
    End Sub

    Private Sub Button_Click(sender As Object, e As EventArgs)
        Dim f As New Form()
        Dim calendar As New MonthCalendar()

        f.FormBorderStyle = FormBorderStyle.None
        f.Size = calendar.Size    'デバッグモードでSizeを直接見た場合とcalendarの中のsizeを見た場合で値が異なり、
                                  'インスタンスを経由したあとに、再度Sizeを直接見ると値が反映されている。
        f.Controls.Add(calendar)
        f.Show()
    End Sub
End Class

試したこと

コンソールに出力した場合はSizeを直接見た場合の値が出力されます。
コントロールをDataGridViewやButtonに変えて確認したところ、特に問題はありませんでした。(Sizeに乖離がない)

補足情報(言語/FW/ツール等のバージョンなど)

環境は
Windows7
VisualStudio2010
です。

また似たような問題がDataTableにおいても発生しております。
こちらはデータバインディングでDataTable型のプロパティの内容をDataGridViewに表示しているのですが、
プロパティを更新した後にデバッグモードでプロパティの値を直接確認しないとDataGridViewに反映されません。
(デバッグモードでプロパティの値を見ることで動作が変化するという共通点があるため一応この情報も載せておきました。)

もしこの現象の原因や解決方法に心当たりがあれば教えていただけないでしょうか?
よろしくお願いします。

追記
カレンダが載っているフォームのサイズに関してはAutoSizeModeをGrowAndShrink、AutoSizeをtureに変更することで解決できました。
ただデバッグモードでプロパティの値を見ることで動作が変化するという現象は解決できておりませんので引き続きお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

アップされているコードで f.Size = calendar.Size の行にブレークポイントを設定し、デバッグ実行してその行で実行を止め、マウスのカーソルを f.Size と calendar.Size の Size に置いたとき、大きさが違うと言ってますか?

であれば、それは当たり前のような気がしますが。

ステップオーバー (F10) で次の行に進めてから、同様にマウスのカーソルを f.Size と calendar.Size の Size に置いて調べてみてください。同じになるのでは?

【追伸】

コメント欄に「ご参考に、回答欄に自分が検証した際の画像をアップしておきます」と書きましたが、ここには自分は画像をアップできないようですので、自分が使っているレンタルサーバーにアップしてそれへのリンクを張っておきます。

http://surferonwww.info/BlogEngine/image.axd?picture=2017%2f10%2fdebug.jpg

ちなみに、自分の環境は Windows 10 Pro 64-bit, VS2015 Community, .NET 4.6.1, Any CPU 32 ビット優先, Debug ビルドです。

【2017/10/29 追記】

下の 2017/10/29 11:26 のコメントに「その結果を回答欄に追記しておきます」と書きましたように、自分が調べた結果を書いておきます。

念のため問題は何かを書いておきますと、

質問者さんのコードの f.Size = calendar.Size で、calendar の中身をデバッガで見ないと、calendar の真のサイズが calendar.Size に反映されないのは何故か?

ということですよね。

まず、MonthCalendar の特殊性として、そのサイズを決定するのは使用されるフォントだけで(MonthCalendar.Size プロパティの設定では変えられない)、フォントが決まらないとサイズが決まらないということがあります。

ここからは想像が入っていますが、以下のようなことだと思われます。

(1) Dim calendar As New MonthCalendar() の時点ではフォントが不明なので真のサイズも不明。

(2) f.Size = calendar.Size の時点でも、依然としてフォントが不明なので真のサイズも不明。

(3) デバッグ実行して calendar.Size の Size にマウスカーソルを当てると Width = 178, Height = 155 という値が取得されるが、それはデフォルト(?)の値で、フォントを考慮した真のサイズではない。

(4) calendar.Size の calendar にマウスカーソルを当て開くと、その時点で calendar が完全に初期化される。すなわち、使用されるフォントに応じて真のサイズが Size プロパティに設定される。

(5) なので、その後で calendar.Size の Size にマウスカーソルを当てると真のサイズが取得できる。

上記の想像を裏付ける Microsoft の公式文書などは見つからないのですが、以下のコードで検証した結果が、多分上記の想像は正しいことを裏付けていると思います。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Button button = new Button();
            button.Click += Button_Click;
            this.Controls.Add(button);
        }

        private void Button_Click(object sender, EventArgs e)
        {
            Form f = new Form();
            Size size1 = f.Size;    // size1 = {Width = 300 Height = 300}
            f.Size = new Size(200, 200);
            size1 = f.Size;         // size1 = {Width = 200 Height = 200}

            MonthCalendar calendar = new MonthCalendar();
            Size size2 = calendar.Size;     // size2 = {Width = 178 Height = 155}
            calendar.Size = new Size(200, 200);
            size2 = calendar.Size;          // size2 = {Width = 178 Height = 155}
            f.Controls.Add(calendar);
            size2 = calendar.Size;          // size2 = {Width = 178 Height = 155}
            f.Show();
            size2 = calendar.Size;          // size2 = {Width = 199 Height = 162}

            f.ClientSize = calendar.Size;
        }
    }
}


calendar が完全に初期化される、すなわち、使用されるフォントに応じて真のサイズが Size プロパティに設定されるのは、上記のコードでは f.Show(); の時点のようです。

その後であれば、calendar.Size で真のサイズを取得でき、それを Form の Size に設定してやれば期待される結果になります。(上のコードで検証済み)

投稿 2017/10/28 13:33

編集 2017/10/29 12:09

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/28 13:44

    そうではなく、そのブレークポイントの場所でcalendar.SizeのSizeの中を見た場合と同じくcalendar.Sizeのcalendarの中のSizeを見た場合で値が異なっています。
    説明が下手で上手く伝わっていなく申し訳ありません。

    キャンセル

  • 2017/10/28 14:38

    上のレスを書き直すと・・・

    アップされているコードで f.Size = calendar.Size の行にブレークポイントを設定し、デバッグ実行してその行で実行を止め、ローカルの calendar の中の Size プロパティの Width, Height の値と、マウスのカーソルを calendar.Size の Size に置いたときに表示される Width, Height の値が違うと言ってますか?

    だとすると、それはあり得ないです。やり方・見方の問題ではないのでしょうか?

    キャンセル

  • 2017/10/28 15:11

    はい、その認識で間違いありません。
    やはり私の見方に問題があるのでしょうか?

    見方としては
    1.calendar.SizeのSizeにフォーカスを当て中を確認します(width=178, Height=155)。
    2.calendar.Sizeのcalendarにフォーカスを当て中を確認します(width=220, Height=189)。←1.と値が異なる
    3.再度1.と同様にSizeにフォーカスを当て中を確認します(width=220, Height=189)。←2.での値が反映されている。
    といった感じです。
    何か問題はあるのでしょうか?ちなみにVisualStudio2017でも同様の現象を確認できます。

    キャンセル

  • 2017/10/28 16:49

    やり方が違うようですが、それで Width, Height が変わる理由が分かりません。とりあえず、ご参考に、回答欄に自分が検証した際の画像をアップしておきます。

    キャンセル

  • 2017/10/28 17:03

    ひょっとして、VB.NET と C# の違い・・・ということもなさそうな気はしますが・・・

    キャンセル

  • 2017/10/28 17:23

    わざわざ画像を上げてくださりありがとうございます。
    それで気づいたのですが、画像下のローカルエリアでcalendarを開けてから(▽を押してから)コード部分のSizeにフォーカスを当てたように見えます。その場合、上で書いた2.と3.を行ったことになり整合性が取れます(本来こうなって欲しいのですが)。
    ちなみにC#でも同じ現象が確認できました。

    また間違ってベストアンサーボタンを押してしまいました。申し訳ありません。

    キャンセル

  • 2017/10/28 17:25 編集

    すみません、話が理解できてなかったです。calendar の中身をデバッガで見ると、その Size が calendar.Size に反映されるのですね。それは再現できました。理由は分かりません。ちょっと調べてみます。

    キャンセル

  • 2017/10/29 11:26

    上のコメントに書きましたように調べてみました。その結果を回答欄に追記しておきます。

    キャンセル

  • 2017/10/29 15:29

    なるほど、描画処理の中に真のSizeを決定する処理が組み込まれてるといった感じでしょうか。
    デバッガは単純にリフレクションで値を取ってきていると思っていましたがそういうわけではなさそうですかね?(もしくはgetかなにかでイベントを発火させている?)

    SurferOnWwwさん、わざわざ検証などもしていただき本当にありがとうございました。おかげさまで納得のいく答えを得ることができました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.46%

関連した質問

同じタグがついた質問を見る

  • VB.NET

    698questions

    Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

  • Visual Studio 2010

    111questions

    Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

  • Windows Forms

    62questions

    Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

  • .NET Framework 4.0

    51questions

    Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。