私はListView
WPFコントロールにGridView
を持っています。私はGridView
列の内容が変更されたときに列のサイズを変更したいと思います。ListView内のGridView列の強制的なサイズ変更
私はいくつかの異なるデータセットを持っていますが、私が1つから別のものに変更すると、各カラムのサイズは以前のデータに適合します。私は動的に更新したいと思います。どうやってやるの?
私はListView
WPFコントロールにGridView
を持っています。私はGridView
列の内容が変更されたときに列のサイズを変更したいと思います。ListView内のGridView列の強制的なサイズ変更
私はいくつかの異なるデータセットを持っていますが、私が1つから別のものに変更すると、各カラムのサイズは以前のデータに適合します。私は動的に更新したいと思います。どうやってやるの?
あなたはピクセル単位で最長の文字列を測定し、それに応じて、列幅を調整することができます:
Graphics graphics = this.CreateGraphics();
SizeF textSize = graphics.MeasureString("How long am I?", this.Font);
あなたはこれらの長さの比として各列をサイズ変更するためのアルゴリズムを作成した場合、あなたは良い結果を取得する必要があります。
これはWPFとバインディングではうまくいきません。 –
最後に、今回はいくつかの結果が得られました。私は、最初に行われたのと同じ自動サイズ設定を行う方法と、列ヘッダーのグリッパーをダブルクリックする方法を見つけました。
public void AutoSizeColumns()
{
GridView gv = listView1.View as GridView;
if (gv != null)
{
foreach (var c in gv.Columns)
{
// Code below was found in GridViewColumnHeader.OnGripperDoubleClicked() event handler (using Reflector)
// i.e. it is the same code that is executed when the gripper is double clicked
if (double.IsNaN(c.Width))
{
c.Width = c.ActualWidth;
}
c.Width = double.NaN;
}
}
}
素晴らしい解決策です。ありがとう。 –
カラムのActualWidth
にバインドする方法はありませんか?何かが好きです:
<GridViewColumn x:Name="column1" Width="{Binding ElementName=column1, Path=ActualWidth}" />
私はこれを試して初めて動作します。バインドエラーはありません。
Oskarsの答えをもとに、コンテンツの変更時に自動的に列のサイズを調整するブレンド動作を示します。
/// <summary>
/// A <see cref="Behavior{T}"/> implementation which will automatically resize the automatic columns of a <see cref="ListView">ListViews</see> <see cref="GridView"/> to the new content.
/// </summary>
public class GridViewColumnResizeBehaviour : Behavior<ListView>
{
/// <summary>
/// Listens for when the <see cref="ItemsControl.Items"/> collection changes.
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
var listView = AssociatedObject;
if (listView == null)
return;
AddHandler(listView.Items);
}
private void AddHandler(INotifyCollectionChanged sourceCollection)
{
Contract.Requires(sourceCollection != null);
sourceCollection.CollectionChanged += OnListViewItemsCollectionChanged;
}
private void RemoveHandler(INotifyCollectionChanged sourceCollection)
{
Contract.Requires(sourceCollection != null);
sourceCollection.CollectionChanged -= OnListViewItemsCollectionChanged;
}
private void OnListViewItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
var listView = AssociatedObject;
if (listView == null)
return;
var gridView = listView.View as GridView;
if (gridView == null)
return;
// If the column is automatically sized, change the column width to re-apply automatic width
foreach (var column in gridView.Columns.Where(column => Double.IsNaN(column.Width)))
{
Contract.Assume(column != null);
column.Width = column.ActualWidth;
column.Width = Double.NaN;
}
}
/// <summary>
/// Stops listening for when the <see cref="ItemsControl.Items"/> collection changes.
/// </summary>
protected override void OnDetaching()
{
var listView = AssociatedObject;
if (listView != null)
RemoveHandler(listView.Items);
base.OnDetaching();
}
}
この動作は、新しい 'ActualWidth'が計算されるまでに時間がかかることを考慮していません。したがって、 'ActualWidth'は依然として内容に合うほど小さすぎることがあります。 – Danielku15
@ Danielku15あなたはそれが起こっていることを知っていますか?私はこの問題を解決するために働くことができるので、小さなサンプルが素晴らしいだろう。 – Lukazoid
私はObservableCollectionにバインドされたListViewを持っています。私は40x40ptである私のCellTemplateのコントロールを持っています。ビヘイビアをアタッチするとOnListViewItemsCollectionChangedメソッドが実行されますが、ActualWidthはまだ小さすぎます(私の場合は25pt)。結果:それは切り取られます。ハンドラが実行されたときにレイアウトプロセスが実行されなかったようです。 – Danielku15
私のような古いであり、ここではその後、VB.NETを希望する場合は、Oskarsコードだ:
Public Sub AutoSizeColumns()
Dim gv As GridView = TryCast(Me.listview1.View, GridView)
If gv IsNot Nothing Then
For Each c As GridViewColumn In gv.Columns
If Double.IsNaN(c.Width) Then
c.Width = c.ActualWidth
End If
c.Width = Double.NaN
Next
End If
End Sub
これは、WPFで素晴らしい作品、ついに誰かがこれを働いています。オスカーに感謝します。
私も同じ問題があります。データソースを変更すると、列の幅のサイズが変更されません。私は、ソースを設定してAutoSizeColumnsメソッドなどを呼び出すことに満足しています。 –
+1、これは私をナッツ運転しています! – Oskar