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

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

新規登録して質問してみよう
ただいま回答率
85.47%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

2回答

464閲覧

C# 「デザイナーでハンドルされない例外」のエラーが表示され、フォームのデザインが表示されない

mechi

総合スコア1

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

2クリップ

投稿2024/04/18 07:39

実現したいこと

現在、Visual StudioでC#を用いてアンケートアプリケーションを作成しています。
画面遷移が多くなるのですが、フォームの上にユーザコントロールを配置し、そのユーザコントロールのtrue/falseの切り替えで実現させる考えです。

発生している問題・分からないこと

途中まで問題なく動作していましたが、あるときからフォームのデザイナーを開こうとすると、唐突に赤丸にバツマーク付きのポップアップウィンドウで「デザイナーでハンドルされない例外がコントロール StressCheck_App.uc_sectionでスローされ、無効になりました。」という旨のエラーが表示されるようになりました。特に何か特別なことをした覚えはありません。
ポップアップを消してフォームのデザイナーを見てみると、エラーポップアップで指摘されているユーザコントロール(uc_section)意外は問題なく表示されているのですが、問題のコントロールuc_sectionは赤枠にエラーメッセージが表示されていてボタンなどのデザインが表示されていません。

エラーメッセージ

error

1デザイナーでハンドルされない例外がコントロール StressCheck_App.uc_sectionでスローされ、無効になりました。 2例外: 3 Method not found: 'Void System.Diagnostics.Diagnostic.Source.Write(System.String, !!0)'. 4 5スタックトレース: 6 at StressCheck_App.uc_section.uc_section_Load(Object sender, EventArgs E10142354365)

該当のソースコード

MainForm.cs

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using Microsoft.Data.SqlClient; 10using Microsoft.Identity.Client; 11using System.Windows.Forms; 12using System.DirectoryServices.ActiveDirectory; 13 14namespace StressCheck_App 15{ 16 public partial class MainForm : Form 17 { 18 19 public int nowCategory; 20 21 public MainForm() 22 { 23 InitializeComponent(); 24 uc_login1.Visible = true; 25 uc_login1.Dock = DockStyle.Fill; 26 27 uc_Start1.Visible = false; 28 uc_section1.Visible = false; 29 uc_surveya1.Visible = false; 30 } 31 32 private void Form1_Load(object sender, EventArgs e) 33 { 34 } 35 36 public void SwitchUC12() 37 { 38 uc_login1.Visible = false; 39 uc_Start1.Visible = true; 40 } 41 42 public void SwitchUC23() 43 { 44 uc_Start1.Visible = false; 45 uc_section1.Visible = true; 46 } 47 48 public void SwitchUC34() 49 { 50 uc_section1.Visible = false; 51 uc_surveya1.Visible = true; 52 } 53 54 55 } 56} 57

uc_section.cs

1using Microsoft.Data.SqlClient; 2using System; 3using System.Collections.Generic; 4using System.ComponentModel; 5using System.Data; 6using System.Drawing; 7using System.Linq; 8using System.Text; 9using System.Threading.Tasks; 10using System.Windows.Forms; 11 12namespace StressCheck_App 13{ 14 public partial class uc_section : UserControl 15 { 16 public uc_section() 17 { 18 InitializeComponent(); 19 } 20 21 private void uc_section_Load(object sender, EventArgs e) 22 { 23 try 24 { 25 using var sql = Db.Conn.CreateCommand(); 26 sql.CommandText = "SELECT TITLE FROM QUESTION_TITLE WHERE Q_CATEGORY = @Q_CATEGORY"; 27 sql.Parameters.AddWithValue("@Q_CATEGORY", "A"); 28 29 using var reader = sql.ExecuteReader(); 30 if (reader.Read()) 31 { 32 secTitle.Text = (string)reader["TITLE"]; 33 } 34 else 35 { 36 MessageBox.Show("SQL検索エラー"); 37 } 38 39 } 40 catch (SqlException ex) 41 { 42 Db.ErrorMessage(ex); 43 } 44 } 45 46 private void btnStart_Click(object sender, EventArgs e) 47 { 48 var objectLoginClass = (MainForm)FindForm(); 49 objectLoginClass.SwitchUC34(); 50 } 51 } 52} 53

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

同様のエラーはいくつか見つかりましたが、対処法を理解することができませんでした。

補足

C#初心者なもので非常にお見苦しいコードになっているかと思われます、申し訳ありません。
解決へのアドバイスをいただけますと幸いです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2024/04/18 07:59 編集

試しに private void uc_section_Load(object sender, EventArgs e) の中身の処理を全てコメントアウトして空っぽ状態にしたらどうなりますか? コンストラクタとかLoadイベントのハンドラは,デザイナも実行する(いつ?開くときに?)という話だったと思うので,そこらへんの箇所に まともな実行時でないと無理な処理コード が書いてあるとそういうことになります.
fana

2024/04/18 08:31 編集

上記が原因であった場合, 【 DesignMode というプロパティを見てやって「デザイナ時にはやらない」という形に実装する】という対処方法があるにはあるのですが…… この DesignMode というプロパティが曲者で,想定通りに働かない場合が多々ある様子で結局ダメダメであり,そこらへんの話をネット検索してみれば,どうにかして「今デザイナが実行しているのか否か」というのを(このプロパティを見るのではない別の方法で)判定するみたいな話が見つかったりするハズです. こういうのとか https://stackoverflow.com/questions/1166226/detecting-design-mode-from-a-controls-constructor https://atmarkit.itmedia.co.jp/bbs/phpBB/viewtopic.php?topic=15316&forum=7
mechi

2024/04/18 08:15

早速のご回答ありがとうございます。大変助かります。ご指定いただきました箇所について、コメントアウトをして実行してみました。 uc_section.csの32行目などでDBから取得した値をラベルに設定しておりましたので、コメントアウトしたことでそちらがリセットされた状態で実行されました。具体的にはラベルsecTitleのTextがリセットされ、デフォルトの"label1"という文字列で表示されました。 また、MainForm.csのデザイナーを開いたところ、赤枠エラーで表示されていなかったコンポーネントのデザインが表示されています。 (ちなみに、元々実行自体はできる状態でした。質問文に記載するのを忘れており、すみません。)
fana

2024/04/18 08:20 編集

> ~にしたらどうなりますか? というのは,「そのようにして実行したらプログラムの動作がどうなるか」という話ではなくて,「そうすればとりあえずデザイナが変な文句を吐かなくなりませんか?」という意味です. とりあえずデザイナの謎エラーが出なくなるのであれば,私が述べた話が原因であろうと推測します.
mechi

2024/04/18 08:24

質問の意図がうまく汲めず申し訳ありません... デザイナーのエラーは解消されました。エラーなく読み込めています。
fana

2024/04/18 10:29 編集

> デザイナーのエラーは解消されました。エラーなく読み込めています。 であれば,状況としてはそういう話なのだろうと思うので,私の2つめのコメントが問題解決のヒントになるかな? とか想像します. (私自身,この問題への 良い対処方法 を知っているわけではないので,良い感じの解決方法を見つけられた場合には自己回答の形で共有して欲しいところです.)
YAmaGNZ

2024/04/18 10:48

ユーザーコントロールのLoadイベントには他の物へアクセスするようなコードは書かないほうがいいかと思います。 Initializeといったメソッドを作成し、フォームのほうから初期化が必要な時に呼び出す形がいいと思います。 それであればDesignModeプロパティの問題も回避できますし
guest

回答2

0

cs

1public static class ControlExtentions 2{ 3 public static bool DesignModeEx(this System.Windows.Forms.Control ctrl) 4 { 5 try 6 { 7 if (_DesignModeEx.HasValue ) 8 return _DesignModeEx.Value; 9 10 // LicenseManagerがDesigntimeかどうかを検出する 11 if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime) 12 { 13 _DesignModeEx = true; 14 return _DesignModeEx.Value; 15 } 16 17 // コントロールのDesignModeを親まで辿って判定する 18 // 最上位コントロールのみDesignModeを検出できる 19 var ctrlTmp = ctrl; 20 while (ctrlTmp != null) 21 { 22 if ((ctrlTmp.Site != null) && ctrlTmp.Site.DesignMode) 23 { 24 _DesignModeEx = true; 25 return _DesignModeEx.Value; 26 } 27 ctrlTmp = ctrlTmp.Parent; 28 } 29 } 30 catch 31 { 32 } 33 34 // デザインモード状態が検出できなかった場合はFalse 35 _DesignModeEx = false; 36 return _DesignModeEx.Value; 37 } 38 private static bool? _DesignModeEx; 39}

(フォームデザイナ上での値)
フォームデザイナ上での値

原因は、既に他の方が言われているようにフォームデザイナで実行されてはいけない処理が実行されていることに起因していると思うので、フォームデザイナで実行されているかどうかDesignModeプロパティを判定してLoadイベントの処理を行わないようにすればいいのですが、入れ子になっているコントロールはDesignModeプロパティが正しく機能しないので、昔はそのような場合は上記のような感じの処理で判定していました。(情報元は忘れました)
本当に正しいやり方なのか?という確信は持っていません。また、コンストラクタでは機能しません。

Loadイベントの他にも、フォームデザイナからコントロールのイベントハンドラが実行される場合もあるので、そういう箇所でDB処理をやっているなら、同じように判定して回避する必要があります。

投稿2024/04/23 04:37

編集2024/04/23 04:48
nururi

総合スコア98

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2024/04/23 09:14

ええと質問は解決されたということでしょうか? そうであれば質問を「解決済」にしてください。 [ヘルプ|質問を解決済みにしたい](https://teratail.com/help#resolve-question) > 本当に正しいやり方なのか?という確信は持っていません。また、コンストラクタでは機能しません。 それともこの辺が追加の疑問ということでしょうか?? であれば回答でなく質問に追記をしてください。 実装に関しては「LicenseManager.UsageMode」は、おそらく間違った使い方なんでしょう。 その下はIsAncestorSiteInDesignModeとほぼ同等ですが、命名や実装は下記を読んだ上でなお不満がある場合のみオレオレ実装にすべきでしょう。 [Add IsAncestorSiteInDesignMode for Control · Issue #4146 · dotnet/winforms](https://github.com/dotnet/winforms/issues/4146) [Implement IsAncestorSiteInDesignMode. by KlausLoeffelmann · Pull Request #5375 · dotnet/winforms](https://github.com/dotnet/winforms/pull/5375) 「こういう場合の一般的な解決法」という意味でしょうか? 私はアマチュアなのでよくわかりませんが、DB処理があちこちあるのもわかりにくいのでどこかにまとめて一括管理したらどうでしょうね。 デザイン中はnullになってるとかダミー処理が走るとかを、全部わかってるはずのMainForm(あるいはProgram.cs?)で切り替えるみたいな。
nururi

2024/04/24 01:10 編集

私は質問者じゃないので解決済みにはできませんが… なんか質問者へのコメントと勘違いされてます? 仰るとおり、.NET6以降ではIsAncestorSiteInDesignMode プロパティを使うのがいいでしょうね。 私が自ライブラリに独自デザインモード判定を導入したのは2019年頃で、WinFormsプロジェクトは.NET Frameworkの既存プロジェクトの保守が多いので、結局あとから追加されたものは使えないことが多いです。 必要ならオレオレ実装だろうが何だろうが実装し、欲しい結果が得られれば別にそれでいいです。 DB処理云々については、質問のソースのLoadイベントで書いてるけど、他のイベントハンドラでもやってるなら気を付けてね程度のニュアンスです。実際にDB処理をどうすべきかについては、質問の本筋から外れるのでコメントは控えておきます。
TN8001

2024/04/26 10:47 編集

> なんか質問者へのコメントと勘違いされてます? すいません。質問者が自己回答したものだと勘違いしていました。 質問者が「質問へのコメント」への返答はあったので、私の回答にリアクションがないのにやきもきしていたため確認が不十分でした。 そしてこのコメントの通知が来なかったため、気が付くのが遅れたこともお詫びします。
guest

0

cs

1private void uc_section_Load(object sender, EventArgs e) 2{ 3 if (DesignMode) return; 4// 以下略

で解決するのであればそれでいいと思います(FormからUserControlを一旦削除して、置きなおさないとダメかもしれません)


fanaさんの言うように入れ子になっていたりすると、DesignModeは(我々の期待通りには)使えません。
Design Mode check · Issue #3300 · dotnet/winforms

.NET6以降であればプロパティが新設されたようです(コンストラクタ内では使えません)
Control.IsAncestorSiteInDesignMode プロパティ (System.Windows.Forms) | Microsoft Learn

使えない場合は自分で作っちゃえばいいんですかねぇ?(オレオレ実装が氾濫するよりはましな気が^^;
Implement IsAncestorSiteInDesignMode. by KlausLoeffelmann · Pull Request #5375 · dotnet/winforms

投稿2024/04/18 10:41

TN8001

総合スコア9326

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問