Reputation: 4170
I want to create a ListView that has two columns with a fixed width and a third column to fill in the remaining space. So something like this:
<ListView>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="*" />
<GridViewColumn Header="Age" Width="50" />
<GridViewColumn Header="Gender" Width="50" />
</GridView>
</ListView.View>
</ListView>
The problem is I can't find a way to get the Name
column to fill in the remaining space, as setting the width to *
doesn't work. It looks like there is a way to do this with a value converter, but it seems like there should be a simpler way. Like with a DataGrid control, you can specify the widths of columns with *
s.
Upvotes: 41
Views: 57110
Reputation: 1
Yet another MVVM solution. We can use MultiValueConverter for our column that should fill the remaining space. This method requires reflection to get DesiredWidth set of other columns.
<ListView>
<ListView.Resources>
<conv:GridViewColumnWidthConverter x:Key="GridViewColumnWidthConverter"/>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Name">
<GridViewColumn.Width>
<MultiBinding Converter="{StaticResource GridViewColumnWidthConverter}" ConverterParameter="*">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ListView}}" Path="ActualWidth" />
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type GridView}}" />
<Binding RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</GridViewColumn.Width>
</GridViewColumn>
<GridViewColumn Header="Age" Width="50" />
<GridViewColumn Header="Gender" Width="50" />
</GridView>
</ListView.View>
</ListView>
Converter:
public class GridViewColumnWidthConverter : IMultiValueConverter
{
private static readonly System.Reflection.PropertyInfo s_piDesiredWidth;
static GridViewColumnWidthConverter()
{
var pi = typeof(GridViewColumn).GetProperty("DesiredWidth",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
Debug.Assert(pi != null);
s_piDesiredWidth = pi;
}
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (parameter is string param && param == "*" && values.Length==3 && values[0] is double actualWidth && actualWidth > 0d)
{
if (values[1] is GridView gridView && values[2] is GridViewColumn column && s_piDesiredWidth != null)
{
double w = 0d;
foreach (var col in gridView.Columns)
{
if (col == column)
continue;
w += col.ActualWidth > 0 ? col.ActualWidth : (double)s_piDesiredWidth.GetValue(col);
}
double desiredWidth = actualWidth - w;
return desiredWidth > 100 ? desiredWidth - 25/*scrollbar width*/ : double.NaN;
}
}
return double.NaN;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
}
Upvotes: 0
Reputation: 6312
The solution from David Hanson-Greville's OnTheBlog mentioned in another answer isn't available anymore, even though the blog still exists. I was able to find it on the Wayback Machine and with a few moderations, here it is:
The trick is that you set Stretch=true on your ListView and it will stretch the columns that do not have a width equally.
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace Demo.Extension.Properties
{
///
/// ListViewColumnStretch
///
public class ListViewColumns : DependencyObject
{
///
/// IsStretched Dependency property which can be attached to gridview columns.
///
public static readonly DependencyProperty StretchProperty =
DependencyProperty.RegisterAttached("Stretch",
typeof(bool),
typeof(ListViewColumns),
new UIPropertyMetadata(true, null, OnCoerceStretch));
///
/// Gets the stretch.
///
/// The obj.
///
public static bool GetStretch(DependencyObject obj)
{
return (bool)obj.GetValue(StretchProperty);
}
///
/// Sets the stretch.
///
/// The obj.
/// if set to true [value].
public static void SetStretch(DependencyObject obj, bool value)
{
obj.SetValue(StretchProperty, value);
}
///
/// Called when [coerce stretch].
///
///If this callback seems unfamilar then please read
/// the great blog post by Paul Jackson found here.
/// http://compilewith.net/2007/08/wpf-dependency-properties.html
/// The source.
/// The value.
///
public static object OnCoerceStretch(DependencyObject source, object value)
{
ListView lv = (source as ListView);
//Ensure we dont have an invalid dependancy object of type ListView.
if (lv == null)
{
throw new ArgumentException("This property may only be used on ListViews");
}
//Setup our event handlers for this list view.
lv.Loaded += new RoutedEventHandler(lv_Loaded);
lv.SizeChanged += new SizeChangedEventHandler(lv_SizeChanged);
return value;
}
///
/// Handles the SizeChanged event of the lv control.
///
/// The source of the event.
/// The instance containing the event data.
private static void lv_SizeChanged(object sender, SizeChangedEventArgs e)
{
ListView lv = (sender as ListView);
if (lv.IsLoaded)
{
//Set our initial widths.
SetColumnWidths(lv);
}
}
///
/// Handles the Loaded event of the lv control.
///
/// The source of the event.
/// The instance containing the event data.
private static void lv_Loaded(object sender, RoutedEventArgs e)
{
ListView lv = (sender as ListView);
//Set our initial widths.
SetColumnWidths(lv);
}
///
/// Sets the column widths.
///
private static void SetColumnWidths(ListView listView)
{
//Pull the stretch columns fromt the tag property.
List<GridViewColumn> columns = (listView.Tag as List<GridViewColumn>);
double specifiedWidth = 0;
GridView gridView = listView.View as GridView;
if (gridView != null)
{
if (columns == null)
{
//Instance if its our first run.
columns = new List<GridViewColumn>();
// Get all columns with no width having been set.
foreach (GridViewColumn column in gridView.Columns)
{
if (!(column.Width >= 0))
{
columns.Add(column);
}
else
{
specifiedWidth += column.ActualWidth;
}
}
}
else
{
// Get all columns with no width having been set.
foreach (GridViewColumn column in gridView.Columns)
{
if (!columns.Contains(column))
{
specifiedWidth += column.ActualWidth;
}
}
}
// Allocate remaining space equally.
foreach (GridViewColumn column in columns)
{
double newWidth = (listView.ActualWidth - specifiedWidth) / columns.Count;
if (newWidth >= 10)
{
column.Width = newWidth - 10;
}
}
//Store the columns in the TAG property for later use.
listView.Tag = columns;
}
}
}
}
Then you just add the namespace to the XAML file:
xmlns:Extensions="clr-namespace:Demo.Extension.Properties"
and use it on your list view:
<ListView ItemsSource="{Binding Path=Items}" DisplayMemberPath="Name"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Grid.Column="0" Margin="8" Extensions:ListViewColumns.Stretch="true">
Upvotes: 9
Reputation: 10274
Building on some other answers (eg. that of Timores), this is the one I normally use. Unlike those, this solution allows both relative and automatic sizes to co-exist:
public class GridViewColumnRelativeSize {
public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(GridViewColumnRelativeSize), new FrameworkPropertyMetadata(IsEnabledPropertyChanged));
public static bool GetIsEnabled(DependencyObject d) => (bool)d.GetValue(IsEnabledProperty);
public static void SetIsEnabled(ListView d, bool value) => d.SetValue(IsEnabledProperty, value);
public static void IsEnabledPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
if (d is ListView list) {
if (!KnownLists.Contains(list)) {
KnownLists.Add(list);
list.Unloaded += OnUnloaded;
list.SizeChanged += OnSizeChanged;
}
}
else
throw new Exception("ListView expected");
}
public static readonly DependencyProperty RelativeWidthProperty = DependencyProperty.RegisterAttached("RelativeWidth", typeof(double), typeof(GridViewColumnRelativeSize), new FrameworkPropertyMetadata(double.NaN));
public static double GetWidth(DependencyObject d) => (double)d.GetValue(RelativeWidthProperty);
public static void SetWidth(GridViewColumn d, double value) => d.SetValue(RelativeWidthProperty, value);
private static readonly List<FrameworkElement> KnownLists = new();
private static void OnUnloaded(object sender, RoutedEventArgs e) {
var element = (FrameworkElement)sender;
_ = KnownLists.Remove(element);
element.Unloaded -= OnUnloaded;
element.SizeChanged -= OnSizeChanged;
}
private static void OnSizeChanged(object sender, SizeChangedEventArgs e) {
if (sender is ListView listView) {
bool isEnabled = listView.GetValue(IsEnabledProperty) is bool enabled && enabled;
if (isEnabled && listView.View is GridView gridView) {
double TotalUnits = gridView.Columns.Sum(column => {
double width = (double)column.GetValue(RelativeWidthProperty);
return double.IsNaN(width) ? 1 : width;
});
double ActualWidth = listView.ActualWidth - SystemParameters.VerticalScrollBarWidth;
double UnitWidth = Math.Floor(ActualWidth / TotalUnits);
foreach (var column in gridView.Columns) {
double unit = (double)column.GetValue(RelativeWidthProperty);
if (!double.IsNaN(unit))
column.Width = unit * UnitWidth;
}
}
}
}
}
<ListView ns:GridViewColumnRelativeSize.IsEnabled="True">
<ListView.View>
<GridView>
<GridViewColumn />
<GridViewColumn Width="50" />
<GridViewColumn ns:GridViewColumnRelativeSize.Width="2" />
</GridView>
</ListView.View>
Columns with a specific Width
obey the size, without a Width
will be automatically sized, with a GridViewColumnRelativeSize.Width
will be proportionally sized using the value as a factor.
Upvotes: 0
Reputation: 413
I realize this is an old question, but I found this post while trying to get star based solution for multiple columns in a ListView
/GridView
. So I figured I could help some future folks out, as it will answer this question as well.
I had initially implemented a WidthConverter
but this has the obvious limitation that the last column won't "fill", and it was never guaranteed that the row would fit its space, but here it is for those who are curious:
public class WidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var actualWidth = (double)value;
var desiredPercentage = SafeConvert(parameter);
if (actualWidth == 0.0 || desiredPercentage == 0.0) return double.NaN;
var result = actualWidth * (desiredPercentage / 100);
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private double SafeConvert(object pInput)
{
if (pInput == null) return default;
if (double.TryParse(pInput.ToString(), out var result))
{
return result;
}
return default;
}
}
<GridViewColumn Header="My Header"
DisplayMemberBinding="{Binding MyColumnData}"
Width="{Binding Path=ActualWidth, ElementName=MyListView, Converter={StaticResource WidthConverter}, ConverterParameter='10.5'}" />
This works, but it's very reliant on the programmer to hard code parameter values and messy in the sense that the binding needs the ActualWidth
property from the ListView
element. Ultimately it's fairly limited to what it can actually do, especially considering most WPF folks are used to working with GridLength
when it comes to star sizing.
I took various bits and pieces from the solutions posted here as well as elsewhere and developed an MVVM friendly solution based on Attached Properties and Behaviors.
I created an Attached Property using GridLength
to leverage the existing absolute/auto/star logic matching XAML width patterns we're all used to.
public class ColumnAttachedProperties : DependencyObject
{
public static readonly DependencyProperty GridLength_WidthProperty = DependencyProperty.RegisterAttached(
name: "GridLength_Width",
propertyType: typeof(GridLength),
ownerType: typeof(ColumnAttachedProperties),
defaultMetadata: new FrameworkPropertyMetadata(GridLength.Auto));
public static GridLength GetGridLength_Width(DependencyObject dependencyObject)
=> (GridLength)dependencyObject.GetValue(GridLength_WidthProperty);
public static void SetGridLength_Width(DependencyObject dependencyObject, string value)
=> dependencyObject.SetValue(GridLength_WidthProperty, value);
}
The Attached Behavior hooks to both the Loaded and SizeChanged events, and performs some shared logic to size the columns.
Essentially, on the first pass over the columns, it will tally the star values (but doesn't set a width for star columns yet), and then on the second pass targets the star columns, setting the width as a percentage of the remaining width available. I am sure this could be optimized in some way.
public static class ListViewStarSizingAttachedBehavior
{
public static readonly DependencyProperty UseGridLength_WidthProperty = DependencyProperty.RegisterAttached(
name: "UseGridLength_Width",
propertyType: typeof(bool),
ownerType: typeof(ListViewStarSizingAttachedBehavior),
new UIPropertyMetadata(false, RegisterEventHandlers));
public static bool GetUseGridLength_Width(DependencyObject dependencyObject)
=> (bool)dependencyObject.GetValue(UseGridLength_WidthProperty);
public static void SetUseGridLength_Width(DependencyObject dependencyObject, bool value)
=> dependencyObject.SetValue(UseGridLength_WidthProperty, value);
private static void RegisterEventHandlers(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ListView listView)
{
if (e.NewValue is bool booleanValue && booleanValue == true)
{
listView.SizeChanged += ListView_SizeChanged;
listView.Loaded += ListView_Loaded;
}
else
{
listView.SizeChanged -= ListView_SizeChanged;
listView.Loaded -= ListView_Loaded;
}
}
}
private static void ListView_Loaded(object sender, RoutedEventArgs e)
{
CalculateGridColumnWidths(sender);
}
private static void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (sender is ListView listView && !listView.IsLoaded) return;
CalculateGridColumnWidths(sender);
}
private static void CalculateGridColumnWidths(object sender)
{
if (sender is ListView listView && listView.View is GridView gridView)
{
// the extra offset may need to be altered per your application.
var scrollOffset = SystemParameters.VerticalScrollBarWidth - 7;
var remainingWidth = listView.ActualWidth - scrollOffset;
var starTotal = 0.0;
foreach (var column in gridView.Columns)
{
var gridLength = ColumnAttachedProperties.GetGridLength_Width(column);
if (gridLength.IsStar)
{
// Get the cumlative star value while passing over the columns
// but don't set their width until absolute and auto have been set.
starTotal += gridLength.Value;
continue;
}
if (gridLength.IsAbsolute)
{
column.Width = gridLength.Value;
}
else
{
column.Width = double.NaN;
}
remainingWidth -= column.ActualWidth;
}
if (starTotal == 0.0) return;
// now eval each star column
foreach (var column in gridView.Columns)
{
var gridLength = ColumnAttachedProperties.GetGridLength_Width(column);
if (!gridLength.IsStar) continue;
var starPercent = (gridLength.Value / starTotal);
column.Width = remainingWidth * starPercent;
}
}
}
}
And finally to use it in XAML, the ListView
needs implement the attached behavior, and each of the columns implement the attached property. However, if you leave the attached property off the column, it will default Auto
as per the DependencyProperty
s defaultMetadata.
<ListView local:ListViewStarSizingAttachedBehavior.UseGridLength_Width="True"
ItemsSource="{Binding MyItems}" >
<ListView.View>
<GridView>
<GridView.Columns>
<!-- Absolute -->
<GridViewColumn local:ColumnAttachedProperties.GridLength_Width="250"
Header="Column One"
DisplayMemberBinding="{Binding Item1}" />
<!-- Star -->
<GridViewColumn local:ColumnAttachedProperties.GridLength_Width="2*"
Header="Column Two"
DisplayMemberBinding="{Binding Item2}" />
<!-- Auto -->
<GridViewColumn local:ColumnAttachedProperties.GridLength_Width="Auto"
Header="Column Three"
DisplayMemberBinding="{Binding Item3}" />
<!-- Star -->
<GridViewColumn local:ColumnAttachedProperties.GridLength_Width="*"
Header="Column Four"
DisplayMemberBinding="{Binding Item4}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
Seems to work well so far, but I am sure there are some edge cases which will need to be considered. The XAML is a ton cleaner than the width converter. The overall result is more flexible than those already posted as well.
Upvotes: 3
Reputation: 2975
The issue is the column width of a GridViewColumn is double, rather than a GridLength object, and there is no conversion in place to handle the *. Not sure if this is an oversight by the WPF team or not. You would think it should be supported.
Aside from the converter, the only other way I've seen it done is here: http://www.ontheblog.net/CMS/Default.aspx?tabid=36&EntryID=37.
Both are additional work that should not be required. I have found other "weird" things with the ListView and GridView combo so I quit using them. If I need a datagrid I use the 3rd party one we license, if I need a complex ListBox style menu, I just use a templated ListBox.
Upvotes: 9
Reputation: 26484
I was trying to achieve the same thing but then decided I would like my ListView columns to consume a percentage of the ListView instead, the result of this is all columns consuming a portion of space and all space being consumed in the ListView. You could set this up to have whatever percentage you like on the last column to directly achieve your 'fill remaining space on last column' goal.
I find this method fairly robust and reliable (even on resize!) so thought I might share.
I have four columns in my ListView for this example. All you need is to register the SizeChanged
event in your ListView with the below event handler:
private void ProductsListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
ListView listView = sender as ListView;
GridView gView = listView.View as GridView;
var workingWidth = listView.ActualWidth - SystemParameters.VerticalScrollBarWidth; // take into account vertical scrollbar
var col1 = 0.50;
var col2 = 0.20;
var col3 = 0.15;
var col4 = 0.15;
gView.Columns[0].Width = workingWidth*col1;
gView.Columns[1].Width = workingWidth*col2;
gView.Columns[2].Width = workingWidth*col3;
gView.Columns[3].Width = workingWidth*col4;
}
Upvotes: 55
Reputation: 14589
My need was to have all columns with the same width. The above solutions are fine, but I prefer to wrap such a thing in an attached property (MVVM, reusability, etc.). Here is my code, if it can help.
public class StarSizeHelper {
private static readonly List<FrameworkElement> s_knownElements = new List<FrameworkElement>();
public static bool GetIsEnabled(DependencyObject d) {
return (bool) d.GetValue(IsEnabledProperty);
}
public static void SetIsEnabled(ListView d, bool value) {
d.SetValue(IsEnabledProperty, value);
}
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled",
typeof(bool),
typeof(StarSizeHelper),
new FrameworkPropertyMetadata(IsEnabledChanged));
public static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var ctl = d as ListView;
if (ctl == null) {
throw new Exception("IsEnabled attached property only works on a ListView type");
}
RememberElement(ctl);
}
private static void RememberElement(ListView ctl) {
if (! s_knownElements.Contains(ctl)) {
s_knownElements.Add(ctl);
RegisterEvents(ctl);
}
// nothing to do if elt is known
}
private static void OnUnloaded(object sender, RoutedEventArgs e) {
FrameworkElement ctl = (FrameworkElement) sender;
ForgetControl(ctl);
}
private static void ForgetControl(FrameworkElement fe) {
s_knownElements.Remove(fe);
UnregisterEvents(fe);
}
private static void RegisterEvents(FrameworkElement fe) {
fe.Unloaded += OnUnloaded;
fe.SizeChanged += OnSizeChanged;
}
private static void UnregisterEvents(FrameworkElement fe) {
fe.Unloaded -= OnUnloaded;
fe.SizeChanged -= OnSizeChanged;
}
private static void OnSizeChanged(object sender, SizeChangedEventArgs e) {
ListView listView = sender as ListView;
if (listView == null) {
return; // should not happen
}
GridView gView = listView.View as GridView;
if (gView == null) {
return; // should not happen
}
var workingWidth = listView.ActualWidth - SystemParameters.VerticalScrollBarWidth -10; // take into account vertical scrollbar
var colWidth = workingWidth / gView.Columns.Count;
foreach (GridViewColumn column in gView.Columns) {
column.Width = colWidth;
}
}
}
In order to use it:
<ListView ... StarSizeHelper.IsEnabled="true" ... />
(you still to fix the namespace declaration in the XAML, of course)
You can adapt your sizing needs in the OnSizeChanged method.
Upvotes: 2
Reputation: 736
I took the example above (which is great) and improved it slightly to prevent runtime exceptions on resize:
private void tpList_SizeChanged(object sender, SizeChangedEventArgs e)
{
ListView listView = sender as ListView;
GridView gView = listView.View as GridView;
var workingWidth = listView.ActualWidth - (SystemParameters.VerticalScrollBarWidth + 20); // take into account vertical scrollbar
var col1 = 0.50;
var col2 = 0.50;
var t1 = workingWidth * col1;
var t2 = workingWidth * col2;
gView.Columns[0].Width = t1 > 0 ? t1 : 1;
gView.Columns[1].Width = t2 > 0 ? t2 : 1;
}
}
Upvotes: 1
Reputation: 1
Here is a solution that allows one to have multiple ListViews leverage a general "Resize" event handler.
//Using dictionarys as trackers allows us to have multiple ListViews use the same code
private Dictionary<string, double> _fixedWidthTracker = new Dictionary<string, double>();
private Dictionary<string, List<GridViewColumn>> _varWidthColTracker = new Dictionary<string, List<GridViewColumn>>();
private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
ListView lv = sender as ListView;
if (lv != null)
{
//For validation during Debug
VerifyName(lv);
GridView gv = lv.View as GridView;
if (gv != null)
{
if (!_varWidthColTracker.ContainsKey(lv.Name))
{
_varWidthColTracker[lv.Name] = new List<GridViewColumn>();
_fixedWidthTracker[lv.Name] = 0;
foreach (GridViewColumn gvc in gv.Columns)
{
if (!double.IsNaN(gvc.Width)) _fixedWidthTracker[lv.Name] += gvc.Width; else _varWidthColTracker[lv.Name].Add(gvc);
}
}
double newWidthForColumns = e.NewSize.Width - SystemParameters.VerticalScrollBarWidth - _fixedWidthTracker[lv.Name];
int columnsCount = gv.Columns.Count;
int numberOfFixedWithColumns = columnsCount - _varWidthColTracker[lv.Name].Count;
Double newColumnWidth = newWidthForColumns / (columnsCount - numberOfFixedWithColumns);
foreach (GridViewColumn gvc in _varWidthColTracker[lv.Name])
{
gvc.Width = newColumnWidth;
}
}
}
}
/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyName(ListView listView)
{
if (String.IsNullOrEmpty(listView.Name))
{
string msg = "The Name attribute is required to be set on the ListView in order to Bind to this method";
Debug.Fail(msg);
}
}
Upvotes: 0
Reputation: 8828
My problem was similar but I wanted to fix the width of the first column and I also didn't want it to break if I added or removed columns, even at runtime. Thanks @Gary for the tip at https://stackoverflow.com/a/14674830/492
private void ResultsListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
double newWidthForColumnsExceptFirstColumn = ResultsListView.ActualWidth - SystemParameters.VerticalScrollBarWidth - ResultsGridView.Columns[0].Width;
int columnsCount = ResultsGridView.Columns.Count;
Double newColumnWidth = newWidthForColumnsExceptFirstColumn / (columnsCount -1);
for ( int col = 1; col < columnsCount; col++ ) // skip column [0]
{
ResultsGridView.Columns[col].Width = newColumnWidth;
}
}
Upvotes: 0
Reputation: 305
Came across this when looking into a similar problem, my issue was I wanted all columns to be 'Auto' expect the first, which would just fill in the extra space, so I expanded on GONeale's solution.
private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
ListView _ListView = sender as ListView;
GridView _GridView = _ListView.View as GridView;
var _ActualWidth = _ListView.ActualWidth - SystemParameters.VerticalScrollBarWidth;
for (Int32 i = 1; i < _GridView.Columns.Count; i++)
{
_ActualWidth = _ActualWidth - _GridView.Columns[i].ActualWidth;
}
_GridView.Columns[0].Width = _ActualWidth;
}
Then the XAML is simply:
...
<ListView.View>
<GridView>
<GridViewColumn Header="Title" />
<GridViewColumn Header="Artist" Width="Auto" />
<GridViewColumn Header="Album" Width="Auto" />
<GridViewColumn Header="Genre" Width="Auto" />
</GridView>
</ListView.View>
...
This code could also be used on more generically as number of columns isn't hard-coded and with a little tweaking you could probably make the 'fill column' definable through some sort of logic.
Hope it helps someone :)
Upvotes: 18