精彩文章免费看

WPF中用ListView时使GridView中的每列宽度按比例变化并使内容自适应单元宽度

在使用ListView的时候,GridView中的每列宽度默认是没法按比例变化的,我们可以使用一个跟它同大小的Grid,给Grid设置相同数量的列,设置好每列的宽度,然后将其宽度绑定到GridView的列上来实现。

<Grid x:Name="gridContainer">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="150" />
        <ColumnDefinition Width="150"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="0" x:Name="col1"/>
    <Grid Grid.Column="1" x:Name="col2"/>
    <Grid Grid.Column="2" x:Name="col3"/>
    <Grid Grid.Column="3" x:Name="col4"/>
</Grid>
<ListView x:Name="lvMetalPrices" ItemsSource="{Binding Path=Quotation.TransactionMetalPrices}" SelectedItem="{Binding Path=Quotation.TransactionMetalPrice}">
    <!--Make the contents of the ListViewItem to fill the cell-->
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView AllowsColumnReorder="True">
            <GridViewColumn x:Name="colMetalPriceCode" Header="代码" DisplayMemberBinding="{Binding Path=MetalCategory.Code}"  Width="{Binding ElementName=col1, Path=ActualWidth}"/>
            <GridViewColumn x:Name="colMetalPriceDesc" Header="描述" DisplayMemberBinding="{Binding Path=MetalCategory.Description}" Width="{Binding ElementName=col2, Path=ActualWidth}"/>
            <GridViewColumn x:Name="colMetalPricePrice" Header="价格(每盎司)"  Width="{Binding ElementName=col3, Path=ActualWidth}">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox x:Name="txtMetalPrice"  Text="{Binding Path=UIPricePerOz, StringFormat={}{0:N2}}" MinHeight="25" MinWidth="100" VerticalContentAlignment="Center" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn x:Name="colMetalPriceRemark" Header="备注"  Width="{Binding ElementName=col4, Path=ActualWidth}">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox x:Name="txtMetalPriceRemark"  Text="{Binding Path=UIRemark}" MinHeight="25" MinWidth="500" AcceptsReturn="False" MaxLength="255" VerticalContentAlignment="Center"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

上面代码中,第1行到第12行定义了一个跟下面名为lvMetalPrices的ListView对应的Grid名为gridContainer,对应ListView的GridView的列数划分了4列,前3列使用固定的宽度,而第四列使用自适应的宽度。同时在gridContainer里每列放入一个新的Grid,并分别指定不同的名称col1、col2、col3、col4。这四个新的Grid将随着gridContainer的宽度的变化而自动调整宽度(实际因为前三列是固定宽度,默认情况下只有第四列会自动调整)。
在第22、23、24、31行中,我们通过类似的代码Width="{Binding ElementName=colx, Path=ActualWidth}"将每列的宽度跟上面对应的Grid的宽度进行绑定,这样在Grid的宽度进行变化的时候,该GridView中所有列的宽度也会跟着进行对应的变化,从而达到我们的目的。
上面代码中第15到19行的内容,实现了让GridView中每行中的单元格中的内容跟着单元格宽度的变化而变化。
整体实现的效果如下: