トップ回答者
DataGridのカラム幅自動調整後の処理

質問
-
はじめて利用させていただきます。
SV2010 .Net4 C#にて開発しております。
DataGridにてカラム幅を自動調整後、自動調整の状態を解除する方法が分かりません。
自動調整する際には
DataGridColumnHeader.Column.Width = DataGridLength.Auto;
とし、これによりカラム幅が調整されます。
このままだと自動調整され続けてしまうため、設定後自動調整を中止したく
WidthにそのカラムのActualWidthを設定するとまだそれには幅が設定されていないようで適切な幅になりませんでした。
どのように設定すればよいのかご教授お願いします。
回答
-
すみません、
DataGridColumnHeader.Widthプロパティと見間違いをしていました。
ごめんなさい。
それで、試してみて欲しいのですが
header.Column.Width = DataGridLength.Auto;
と、
header.Column.Width = header.Column.ActualWidth;
の間に
dataGrid.UpdateLayout();
を挟むとどうなりますか?
# UIElement.UpdateLayout メソッド (System.Windows)
# http://msdn.microsoft.com/ja-jp/library/system.windows.uielement.updatelayout(v=VS.100).aspx
- 回答としてマーク たう 2011年6月9日 10:48
-
Width を変更した後、実際にレイアウトパスが実行される(で、各セルの中身の長さが測定され最終的に列幅が決定され ActualWidth が実際の値を返すようになる)のは少し後のタイミングになりますからね。
UpdateLayout を呼び出すことでレイアウトパスの実行を強制させることができます。その後 ActualWidth を取得する、というのが一つ。
逆にレイアウトパスの実行まで待つという観点から、Dispatcher.BeginInvoke で ActualWidth の取得を行うというのが一つ(もちろん、DispatcherPriority.Render よりも低い優先順位で)。
- 回答としてマーク たう 2011年6月9日 10:48
すべての返信
-
返信が遅くなってすみません。
エクスプローラのカラムヘッダーのメニューと同じような機能を実装しようとしています。
以下は、エクスプローラの「すべての列のサイズを自動的に変更する」のイメージです。
カラムヘッダにメニューを表示させて、そのメニューのクリックイベントで
foreach (DataGridColumn col in dataGrid.Columns)
{
col.Width = DataGridLength.Auto;
col.Width = col.ActualWidth;
}
としています。こうするとすべてのカラムで「ActualWidth=20」になってしまいます。
よろしくお願いします。
-
こんにちは。
いまいち質問の意味が理解できているか自信が無いですが、
最初の質問文では
DataGridColumnHeader
のColumn.Widthを設定していますよね。
次の投稿では
DataGridColumn.Widthを設定しています。
おそらくですが、
DataGridColumnHeaderとDataGridColumnを同時に設定していませんか?
その場合、DataGridColumnHeaderが優先されたと思いますが。
想定した動きにならないのはその辺が原因な気がします。
今一度、ご自分の書いたソースを点検なさってはいかがでしょうか。
以上、参考になれば幸いです。 -
返信ありがとうございます。
適切でない書き込みをしてしまいすみません。
エクスプローラの「列のサイズを自動的に変更する」と「すべての列のサイズを自動的に変更する」を実装しようとしています。(この処理を混同させてしまいました。)
「列のサイズを自動的に変更する」の処理では、メニュークリックイベントにて右クリックされたカラムヘッダ(header)に対して
header.Column.Width = DataGridLength.Auto;
header.Column.Width = header.Column.ActualWidth;
の処理をしています。「すべての列のサイズを自動的に変更する」の処理では、メニュークリックイベントにて
foreach (DataGridColumn col in dataGrid.Columns)
{
col.Width = DataGridLength.Auto;
col.Width = col.ActualWidth;
}
の処理をしています。いずれも、この処理の後、対象カラムが「ActualWidth=20」になってしまいます。
再度、ご教授の程よろしくお願いします。
-
処理としては、DataGridColumnのWidthを設定しています。
header.ColumnはDataGridColumnだと考えているのですが、間違いでしょうか。
header.Column.Width = DataGridLength.Auto;
を処理させたメニューイベントの関数内では
DataGridLength.Autoをセット後には
header.Column.ActualWidth=20
header.ActualWidth=「サイズ調整前の幅」
となっていました。
再度同じカラムに対してイベントを処理してみると
DataGridLength.Autoをセットする前に
header.Column.ActualWidth=「前回のサイズ調整後の幅」
header.ActualWidth=「前回のサイズ調整後の幅」
が取得できます。
Columnのサイズ変更イベントを拾ってそこで処理するのでしょうか。
-
すみません、
DataGridColumnHeader.Widthプロパティと見間違いをしていました。
ごめんなさい。
それで、試してみて欲しいのですが
header.Column.Width = DataGridLength.Auto;
と、
header.Column.Width = header.Column.ActualWidth;
の間に
dataGrid.UpdateLayout();
を挟むとどうなりますか?
# UIElement.UpdateLayout メソッド (System.Windows)
# http://msdn.microsoft.com/ja-jp/library/system.windows.uielement.updatelayout(v=VS.100).aspx
- 回答としてマーク たう 2011年6月9日 10:48
-
Width を変更した後、実際にレイアウトパスが実行される(で、各セルの中身の長さが測定され最終的に列幅が決定され ActualWidth が実際の値を返すようになる)のは少し後のタイミングになりますからね。
UpdateLayout を呼び出すことでレイアウトパスの実行を強制させることができます。その後 ActualWidth を取得する、というのが一つ。
逆にレイアウトパスの実行まで待つという観点から、Dispatcher.BeginInvoke で ActualWidth の取得を行うというのが一つ(もちろん、DispatcherPriority.Render よりも低い優先順位で)。
- 回答としてマーク たう 2011年6月9日 10:48