【问题标题】:How to dynamically change the column width in ListView WPF?如何动态更改 ListView WPF 中的列宽?
【发布时间】:2019-11-09 17:37:48
【问题描述】:

我正在编写 WPF 应用程序。我有一个包含 ListView 的简单 UserControl。 ListView 包含三列。我想根据 UserControl 大小动态更改中间列的宽度,我需要用列表填充整个 UserControl。这是我的 xaml 代码:

<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(); }

    }



转换器正确计算宽度,但屏幕上没有任何反应。尽管返回正确的值 (550),但视图中中间列的宽度绝对为 0。这不是唯一的问题;当我尝试运行此代码时,对计算能力的要求非常高。应用程序开始运行如此缓慢,以至于无法使用它。转换器或 xaml 代码一定有问题,因为如果我剪切它,添加用常量值替换宽度,一切似乎都是正确的。我做错了什么?

【问题讨论】:

  • 转换器中的计算可以直接在 ViewModel 中完成,绑定应该直接从列 Width 到 Datacontext 中的属性。此外,似乎应该将 conserned 列放在 ListView 资源中的 Datatemplate 中,以便在运行时动态应用宽度。

标签: c# wpf xaml


【解决方案1】:

嗯,我试图实现这一目标的方式非常复杂。这是更好的解决方案(正常工作)。在文件后面的代码中,你需要有这样的东西:


        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 文件中命名列,然后在后面的代码中手动更改宽度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多