C# 如何在ListView WPF中动态更改列宽?
我正在写WPF应用程序。我有一个包含ListView的简单用户控件。ListView包含三列。我想根据UserControl的大小动态更改中间列的宽度,我需要用列表填充整个UserControl。以下是我的xaml代码:C# 如何在ListView WPF中动态更改列宽?,c#,wpf,xaml,C#,Wpf,Xaml,我正在写WPF应用程序。我有一个包含ListView的简单用户控件。ListView包含三列。我想根据UserControl的大小动态更改中间列的宽度,我需要用列表填充整个UserControl。以下是我的xaml代码: <UserControl ... d:DesignHeight="540" d:DesignWidth="750"> <UserControl.Resources>
<UserControl
...
d:DesignHeight="540"
d:DesignWidth="750">
<UserControl.Resources>
<Converters:ItemTypeToImageConverter x:Key="ItemTypeToImageConverter"/>
<Converters:ListWidthMultiConverter x:Key="ListWidthMultiConverter"/>
</UserControl.Resources>
<Grid>
<ListView
MinWidth="750"
ItemContainerStyle="{StaticResource MainListItemStyle}"
Background="{StaticResource LightBackgroundBrush}"
BorderThickness="0"
ItemsSource="{Binding ListItems}"
SelectionMode="Single">
<ListView.View>
<GridView
AllowsColumnReorder="False">
<GridViewColumn Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="{x:Type local:MainListItemVM}">
<Image
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="30"
Height="30"
Source="{Binding Type, Converter={StaticResource ItemTypeToImageConverter}}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Name}">
<GridViewColumn.Width>
<MultiBinding
Converter="{StaticResource ListWidthMultiConverter}">
<Binding
Path="ActualWidth"
RelativeSource="{RelativeSource AncestorType=ListView}"/>
<Binding
Path="View.Columns"
RelativeSource="{RelativeSource AncestorType=ListView}"/>
</MultiBinding>
</GridViewColumn.Width>
</GridViewColumn>
<GridViewColumn Width="150" DisplayMemberBinding="{Binding Size}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>
以下是我的转换器代码:
using System;
using System.Collections.Generic;
using System.Windows.Data;
using System.Globalization;
using System.Windows.Controls;
public class ListWidthMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
double userControlWidth = 750;
double columnsWidth = 750;
var columns = values[1] as IList<GridViewColumn>;
if (double.TryParse(values[0].ToString(), out userControlWidth) && columns != null)
{
columnsWidth = columns[0].Width + columns[2].Width;
}
double returnValue = userControlWidth - columnsWidth;
return returnValue > 0 ? returnValue : 0;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
}
使用系统;
使用System.Collections.Generic;
使用System.Windows.Data;
利用制度全球化;
使用System.Windows.Controls;
公共类ListWidthMultiConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
双userControlWidth=750;
双柱宽度=750;
var columns=值[1]为IList;
if(double.TryParse(值[0].ToString(),out userControlWidth)&&columns!=null)
{
columnsWidth=列[0]。宽度+列[2]。宽度;
}
双返回值=userControlWidth-columnsWidth;
返回值>0?返回值:0;
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,文化信息文化){抛出新的NotImplementedException();}
}
转换器正确计算宽度,但屏幕上没有任何变化。尽管返回了正确的值(550),但视图中中间列的宽度肯定是0。这不是唯一的问题;当我试图运行这段代码时,对计算能力的要求非常高。应用程序开始工作的速度太慢,以至于无法使用它。转换器或xaml代码一定有问题,因为如果我剪切它,添加并用常量值替换宽度,一切似乎都是正确的。我做错了什么?嗯,我试图实现这一目标的方式相当复杂。这里有更好的解决方案(工作正常)。在代码隐藏文件中,您需要具有以下内容:
public DirectoryContentList()
{
InitializeComponent();
Application.Current.MainWindow.SizeChanged += ResizeNameColumn;
}
private void ResizeNameColumn(object sender, SizeChangedEventArgs args)
{
var newWidth = Application.Current.MainWindow.ActualWidth - (TypeColumn.Width + SizeColumn.Width + 290);
NameColumn.Width = newWidth > 0 ? newWidth : 0; //Cannot set negative value to the column width
}
首先尝试在xaml文件中命名列,然后在代码隐藏中手动更改宽度。在转换器中完成的计算可以直接在ViewModel中完成,绑定应该直接从列宽到Datacontext中的属性。此外,似乎应该将conserned列放入ListView资源中的Datatemplate中,以便在运行时动态应用宽度。