トップ回答者
入れ子させた UserControl の DesignMode が false になるのを回避したい

質問
-
Form1 に UserControl (A) を置き、A の上に更に UserControl (B) を置いています。
参考画像 (1) 参照。
各コントロールの DesignMode の値を実行時とデザイン時で、以下のコードを
使って Label に出力して比較しました。その結果が、参考画像 (1),(2) です。
Code Snippetprivate void A_Load(object sender, EventArgs e)
{
this.label1.Text = this.DesignMode.ToString();
}参考画像 (1) 実行時 参考画像 (2) デザイン時 デザイン時 (右) に、オレンジ色の UserControl (B) の DesignMode の値が正
しくありません。True であることが期待されます。
DesignMode の意味ないじゃないか!と文句を言いたいところですが、
現実はこの予想外の事態を回避しなければなりません。
何か簡単な方法ないでしょうか?
参考
- 入れ子になったユーザー コントロールの DesignMode プロパティは、 False に Visual Studio .NET または Visual Studio 2005 に常に設定されます。
- 入れ子になったユーザーコントロールの DesignMode プロパティについて - Bug Catharsis
- FIX: Visual Studio .NET でのデザイン ビューでフォームを開くと、エラー メッセージを表示することがあります。- How to: design-time or run-time (again) - MSDN Forums
回答
-
custar さんからの引用 何か簡単な方法ないでしょうか?
DesignModeの挙動を変えることはできないのですから、DesignModeだけで判断するという考え方を捨てるべきでしょう。
DesignModeの他、現在のプロセスが"devenv"であればデザインモードと判断するという手法が使われています。
#Visual Studioに読み込まれていたら、デザインモードと判断する。
-
補足です。同様の内容は、何度もフィードバックされているようです。
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=117130
その中の一つのこのリンクには、Azulean さんご紹介の回避方法が、この報告者によって紹介されてました。
また、KB にもなっていることも、その報告者が書かれてますね。
http://support.microsoft.com/kb/839202結論としてはフィードバック側の通り、修正できないそうです。
他の回避策を考えてみました。
親を含めたいずれかが DesignMode であれば true を返すプロパティをユーザーコントロールに追加します。
親ができるまでは機能しないので、Azulean さんご紹介の方法の方が確実だと思いますが、こちらはプロセス名に依存しない方法になります。Code Snippetprivate new bool DesignMode
{
get
{
bool design = base.DesignMode;Control parent = this.Parent;
while (parent != null)
{
ISite site = parent.Site;
if (site != null) design |= site.DesignMode;
parent = parent.Parent;
}return design;
}
}※追記:些細なことですが、while (!design && parent != null) とした方が効率が良いですね。
すべての返信
-
custar さんからの引用 何か簡単な方法ないでしょうか?
DesignModeの挙動を変えることはできないのですから、DesignModeだけで判断するという考え方を捨てるべきでしょう。
DesignModeの他、現在のプロセスが"devenv"であればデザインモードと判断するという手法が使われています。
#Visual Studioに読み込まれていたら、デザインモードと判断する。
-
Azulean さんからの引用
DesignModeの他、現在のプロセスが"devenv"であればデザインモードと判断す
るという手法が使われています。
# Visual Studioに読み込まれていたら、デザインモードと判断する。
へぇ。そんなのがあったのですね。
LicenseManager を使ったのが英語フォーラムにあったなぁ、と思ったら幾つか
ありました。簡単なのかどうか分からなかったので、そのままにしていました
が、使ってみたら、案外簡単なんですね。
以下に、変更した結果を示します。期待通りです。
Azulean さん、情報ありがとうございます。参考画像 (3) アドバイス後の結果。中も外も True。
-
補足です。同様の内容は、何度もフィードバックされているようです。
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=117130
その中の一つのこのリンクには、Azulean さんご紹介の回避方法が、この報告者によって紹介されてました。
また、KB にもなっていることも、その報告者が書かれてますね。
http://support.microsoft.com/kb/839202結論としてはフィードバック側の通り、修正できないそうです。
他の回避策を考えてみました。
親を含めたいずれかが DesignMode であれば true を返すプロパティをユーザーコントロールに追加します。
親ができるまでは機能しないので、Azulean さんご紹介の方法の方が確実だと思いますが、こちらはプロセス名に依存しない方法になります。Code Snippetprivate new bool DesignMode
{
get
{
bool design = base.DesignMode;Control parent = this.Parent;
while (parent != null)
{
ISite site = parent.Site;
if (site != null) design |= site.DesignMode;
parent = parent.Parent;
}return design;
}
}※追記:些細なことですが、while (!design && parent != null) とした方が効率が良いですね。
-
While this is a known issue,
it is an issue that we cannot fix.
If we change the behavior here
we run the risk of introducing breaking changes to fielded applications.この解釈、上手く分からないのですが、
既に広まってるアプリケーションに影響があるから、もう変えられない、
ということなのかな?
TH01 さんからの引用
他の回避策を考えてみました。
親を含めたいずれかが DesignMode であれば true を返すプロパティをユーザーコントロールに追加します。
私も質問した後、似たように親を辿 (たど) って行き、そのうち1つでも
DesignMode == true ならば、全て true だ!というのを作りましたが、TH01 さんのが綺麗。
- 回答の候補に設定 yone64 2010年5月3日 4:44
-
下記ドキュメントを参考に、デザイン時の Load() の処理を追えるようになりました。
# Visual Studio 2008 Professional ですが。
- チュートリアル : カスタム Windows フォーム コントロールのデザイン時のデバッグ
# 相変わらず文字だけでは分かりづらい。
デザイン時にもプログラムが処理されていることをはっきり認識することが出
来、Form を開いた時によく現れていたインスタンス未設定のメッセージとその
トレース内容の理解にも繋がりました。
Express Edition で散々遊んできましたが、最近の内容では、Professional
(試用版) に依存するところが多くなってきました。Express に当てはまらない
操作が含まれるケースが多くなってきたので、フォーラム移った方がいいですね。