如何根据WPF中的窗口大小调整某个控件的大小?

Joa*_*nge 3 .net c# wpf layout

我有一个ListView控件,我想调整最后一列的大小与Window.的大小同步.因此,如果Window宽度增加100个单位,我希望列的宽度也增加100.

我应该Resize在窗口上使用事件并使用幻数来手动调整列标题的大小,有点像?:

columnHeader.Width = windowSize.X - 400;
Run Code Online (Sandbox Code Playgroud)

Dav*_*ite 7

这是一个使用数据绑定和一些转换器魔术来完成工作的解决方案.

首先,让我们描述一个包含一些数据和3列的简单ListView.

<ListView>
    <ListView.View>
        <GridView>
            <GridViewColumn Width="140" Header="Date" />
            <GridViewColumn Width="140" Header="Day" 
                            DisplayMemberBinding="{Binding DayOfWeek}" />
            <GridViewColumn Width="140" Header="Year" 
                            DisplayMemberBinding="{Binding Year}"/>
        </GridView>
    </ListView.View>

    <sys:DateTime>1/2/3</sys:DateTime>
    <sys:DateTime>4/5/6</sys:DateTime>
    <sys:DateTime>7/8/9</sys:DateTime>
</ListView>
Run Code Online (Sandbox Code Playgroud)

这将使我们到达你的位置.现在,为了让最后一列根据父级宽度增长和缩小,我们需要构建一个转换器并将其连接起来.首先,让我们调整GridView的最后一列以使宽度动态化.

<GridViewColumn Header="Year" DisplayMemberBinding="{Binding Year}">
    <GridViewColumn.Width>
        <MultiBinding Converter="{StaticResource lastColumnMaximizerConverter}">
            <Binding Path="ActualWidth" 
                     RelativeSource="{RelativeSource AncestorType=ListView}"/>
            <Binding Path="View.Columns" 
                     RelativeSource="{RelativeSource AncestorType=ListView}"/>
        </MultiBinding>
    </GridViewColumn.Width>
</GridViewColumn>
Run Code Online (Sandbox Code Playgroud)

我们在这里所做的是创建一个MultiBinding对象,连接一个IMultiValueConverter,并描述了我们想要发送到IMultiValueConverter实现中的几个参数.第一个参数是父ListView的ActualWidth.第二个参数是父ListView上的View.Columns集合.我们现在拥有了计算视图中最后一列最终宽度所需的一切.

现在我们需要创建一个IMultiValueConverter实现.我碰巧在这里有一个.

public class WidthCalculationMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, 
                          object parameter, CultureInfo culture)
    {
        // do some sort of calculation
        double totalWindowWidth;
        double otherColumnsTotalWidth = 0;
        double.TryParse(values[0].ToString(), out totalWindowWidth);
        var arrayOfColumns = values[1] as IList<GridViewColumn>;

        for (int i = 0; i < arrayOfColumns.Count - 1; i++)
        {
            otherColumnsTotalWidth += arrayOfColumns[i].Width;
        }

        return (totalWindowWidth - otherColumnsTotalWidth) < 0 ? 
                     0 : (totalWindowWidth - otherColumnsTotalWidth);
    }

    public object[] ConvertBack(object value, Type[] targetTypes,
                                object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

Psst ..顺便说一下,这不是最安全的代码.你会想要修饰它!这只是一个演示,你知道演示代码是如何的!:)

最后,我们需要在XAML中实例化Converter实例.

<Grid.Resources>
    <Converters:WidthCalculationMultiConverter 
                  x:Key="lastColumnMaximizerConverter"/>
</Grid.Resources>
Run Code Online (Sandbox Code Playgroud)

所以现在我们有一个转换器,根据ListView中列(不包括最后一列)的宽度以及将使用该转换器并发送所需内容的绑定,计算出我们想要制作最后一列的宽度参数并获得"正确答案"并将其应用于最后一列的宽度.

如果你把它放在一起,你现在应该有一个ListView,其中最后一列将始终延伸到父ListView的最大宽度.

我希望这会让你前进,但也帮助你理解我们如何做到这一点,而无需编写代码隐藏和使用WPF提供的更多设施.