同様の問題が発生しました。C#WinformsのタブページサイズとClientSizeが間違っているを参照してください:を含む
を作成しました。のコンテンツは、の幅に基づいて配置されますが、クエリされたTabPageのは、TabPageが少なくとも1回表示されていない限り、間違っています。あなたはすでにあなたの質問に書いたように、同じことを発見しました。UserControl
TabControl
TabPage
TabPage
Size
ClientSize
DisplayRectangle.Size
私が試したことは、すべて成功しませんでした。
- それぞれのハンドルの作成を強制します
TabPage
- プログラムでそれぞれを選択
TabPage
visible = true
それぞれの設定TabPage
PerformLayout
それぞれに呼びかけるTabPage
- 私がもう覚えていない他のいくつかのもの
.netが内部で何をするのか、そして各TabPageを強制的に更新するためにそれを回避する方法を見つけようとさえしましたが、複雑すぎて時間がかかるのでそれをあきらめました。
最終的に機能したもの:
私のさらなる分析は、私のUpdateLayout
関数(UCのLayout
イベントによって呼び出される)にデバッグ印刷を追加しSize
、TabControlと各TabPageのを印刷することでした。そして突然、私のUCは望み通りに動作しました。
これらの値のクエリは、明らかにTabPagesを更新するいくつかの.net関数をトリガーします。さらなるテストでは、UCのイベントでのクエリで十分であることが示されているため、コードに1行だけ追加する必要があります。 ClientSize
DisplayRectangle.Size
TabControl.DisplayRectangle.Size
Layout
var oSize = i_oTabControl.DisplayRectangle.Size;
おそらくコンパイラによって最適化されることを避けてください。
[MethodImpl (MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
public static void TabControlForceUpdateOfTabpageSize (this TabControl i_oTabControl)
{
if (i_oTabControl == null)
return;
var oSize = i_oTabControl.DisplayRectangle.Size;
}
別のテストプロジェクトでも失敗するのを見たことがあるので、あなたの状況ではうまくいかないかもしれないことを認めなければなりません。私はまだ理由を探しています。
注意:テストと開発は、.Net4.6を使用してVS2015Update3で行われました。ソリューションは、デバッグおよびリリースビルドで機能していることが確認されています。
編集:
ソリューションのテストにもう少し時間を費やしました。また、.netソースコードを再度デバッグして、そこで大まかに何が起こっているかを最終的に見つけました。
私のソリューションは、さまざまな理由の組み合わせのために機能しました:
- はの
TabControl
中に配置されますUserControl
。
- の使用サイズは、
UserControl
設計時のサイズとは異なります。これによりLayout
、UCのイベントが発生します。
- サイズの変更はで発生し
InitializeComponent()
ます。これは、UCにまだ親がないことを意味します。
- それぞれ
TabPage
に、独自のサイズではなく、のサイズを使用しています。これはSelectedTab
、非表示のタブページのサイズが適切に更新されておらず、すべてのタブページのサイズが同じであることがすでにわかっているためです(AutoScroll = false
)。
- タブページのコントロールは、選択したタブページのサイズを使用して、アンカーを介さずにプログラムで配置されます(4を参照)。
動作原理は次のとおりです。
- 目標は、のレイアウトを強制する
TabControl
ことTabPage
です。
- これは、実際に表示されている場合にのみ実行されます。ScrollableControl.OnVisibleChanged()`を参照してください。
- TabPageまたはTabControlのみが表示されます。それ自体が表示に設定されていて、すべての親が表示されている場合は、を参照してください
Control.GetVisibleCore()
。コントロールがフォームに追加された場合、フォームは表示されたときに表示されるため、フォームのコンストラクターが実行されているときはコントロールは非表示になります。ただし、コントロールがまだフォームに追加されていない場合、フォームはコントロールの親ではないため、フォームの非表示は無関係になります。
「しかし、私のフォームは表示されているので、機能するはずです」と言うことになります。
はい、そうです。私の状況では、UserControlは別のTabControlの選択されていないTabPageに配置されていました。これは、UCの親が表示されていないことを意味します。ただし、サイズが変更されたとき、UCには親がありませんでした(2.および3を参照)。また、UCのイベントの回避策により、および選択されLayout
たの更新が強制される可能性があります。また、およびすべてのイベントで回避策が存在する場合でも、すべてのタブページのサイズ値は正しいものでした(少なくともいくつかのサイクルの後)。 TabControl
TabPage
Layout
TabControl
TabPage
回避策は、ちょっとしたトリック(テスト済み)でも機能する可能性があります。
親からTabControlを削除し、すべてのタブページを循環して、後で親に追加し直します。
var oParent = tabctrlU.Parent;
oParent.Controls.Remove (tabctrlU);
var tabStart = tabctrlU.SelectedTab;
foreach (TabPage tab in tabctrlU.TabPages)
tabctrlU.SelectedTab = tab;
tabctrlU.SelectedTab = tabStart;
oParent.Controls.Add (tabctrlU);
これにより、更新の強制が有効になります。
ただし、非表示のタブの将来のサイズ変更では機能しません。これで、サイズを変更するたびにイベントがトリガーされるLayout
ため、そこにコードを追加できます。実際、タブコントロールを毎回削除して再度追加することはありません。これはばかげています。したがって、この解決策はあなたのケースにはあまり当てはまらないことを認めなければなりません。しかし、あなた(および他の人)は今、それに対処する方法についていくつかのアイデアを持っています。
すでに自分で解決策を見つけたので、最初のTabPageに移動したくない場合は、ctor内のとその親TabPagePanel1
のサイズと位置を覚えて、(新規)に従ってプログラムでサイズを変更できます。選択したTabPageがそのページに移動された後のサイズ。Panel1
Panel1