5

按照此处类似问题的答案,我能够在 XAML 页面上设置 MinWidth。

我想做的是在所有 ListView 中的所有 GridViewColumn 的控件模板中完成此操作。

这可能吗?

更新:

我在下面尝试了一些简单的示例代码,但它不起作用:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <Style TargetType="{x:Type GridViewColumnHeader}" >
            <Setter Property="MinWidth" Value="200" />
        </Style>
    </Window.Resources>

    <Grid Width="500">
        <Border BorderBrush="Black" BorderThickness="2" Margin="20">
            <ListView SelectionMode="Single">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Header 1" Width="Auto">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="Hello There"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Header="Header 2" Width="Auto" />
                    </GridView>
                </ListView.View>
            </ListView>
        </Border>
    </Grid>
</Window>
4

7 回答 7

9

如果您使用 GridViewColumnHeader 您可以处理大小更改:

  <GridView>
     <GridViewColumn>
        <GridViewColumnHeader Content="HeaderContent" SizeChanged="HandleColumnHeaderSizeChanged"/> 
   ...

在代码中:

    private void HandleColumnHeaderSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs)
    {
        if (sizeChangedEventArgs.NewSize.Width <= 60) {
            sizeChangedEventArgs.Handled = true;
            ((GridViewColumnHeader) sender).Column.Width = 60;
        }
    }
于 2014-12-11T11:00:52.367 回答
4
<Window.Resources>
    <Style TargetType="{x:Type GridViewColumnHeader}" >
        <Setter Property="MinWidth" Value="400" />
    </Style>
</Window.Resources>
于 2012-04-11T00:11:35.883 回答
4
 <ListView>
        <ListView.View>
            <GridView>
                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock MinWidth="100"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                 ...more columns...
            </GridView>
        </ListView.View>
    </ListView>
于 2012-04-10T23:13:58.900 回答
4

我也偶然发现了这个。为了解决它,我必须做两件事:

  1. 修改ListView头部的ControlTemplate。
  2. 在 ControlTemplate 中处理 Thumb 的 DragDelta 事件。

ListView 的标题是GridViewColumnHeader。下面显示的是 GridViewColumnHeader 的 ControlTemplate 的简化版本。正如我们所见,它使用 Canvas 中的Thumb来创建拖动/调整大小效果。

PS:获取完整的GridViewColumnHeader ControlTemplate请参考如何抓取WPF 4.0控件默认模板?

<ControlTemplate TargetType="GridViewColumnHeader">
<Grid SnapsToDevicePixels="True">
    <Border BorderThickness="0,1,0,1" Name="HeaderBorder" ...>
    <!-- omitted -->
    </Border>
    <Border BorderThickness="1,0,1,1" Name="HeaderHoverBorder" Margin="1,1,0,0" />
    <Border BorderThickness="1,1,1,0" Name="HeaderPressBorder" Margin="1,0,0,1" />
    <Canvas>
        <Thumb Name="PART_HeaderGripper">
        <!-- omitted -->
        </Thumb>
    </Canvas>
</Grid>
<ControlTemplate.Triggers>
<!-- omitted -->
</ControlTemplate.Triggers>

所以为了限制GridViewColumnHeader的大小,我们需要hook Thumb的拖动事件(DragStarted、DragDelta、DragCompleted...等)。

原来我们只需要DragDelta事件,只要我们知道DragDeltaEventHandler中的 MinSize 即可。

下面显示的是带有注释的修改后的 XAML。

<Grid Width="500">
    <Border BorderBrush="Black" BorderThickness="2" Margin="20">
        <ListView SelectionMode="Single">
            <ListView.View>
                <GridView>                        
                    <GridViewColumn Header="Header 1" Width="Auto">
                        <!-- Apply a style targeting GridViewColumnHeader with MinWidth = 80 and a ControlTemplate -->
                        <GridViewColumn.HeaderContainerStyle>
                            <Style TargetType="{x:Type GridViewColumnHeader}">
                                <Setter Property="MinWidth" Value="80" />
                                <Setter Property="Control.Template" Value="{DynamicResource myGridViewColumnHeaderControlTemplate}" />
                            </Style>
                        </GridViewColumn.HeaderContainerStyle>**
                    </GridViewColumn>
                    <GridViewColumn Header="Header 2" Width="Auto" />
                </GridView>
            </ListView.View>
        </ListView>
    </Border>
</Grid>

在 myGridViewColumnHeaderControlTemplate 中添加一些 XAML 到:

  1. 将 GridViewColumnHeader 的 MinWidth 绑定到 Canvas 的 MinWidth。
  2. 连接 Thumb 的 DragDelta 事件。
<ControlTemplate x:Key="TemplateGridViewColumnHeader" TargetType="GridViewColumnHeader">
    <!-- omitted -->
    <Canvas MinWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MinWidth, Mode=OneTime}">
        <Thumb x:Name="PART_HeaderGripper" DragDelta="myGridViewColumnHeader_DragDelta">

最后是 myGridViewColumnHeader_DragDelta 函数:

    private void myGridViewColumnHeader_DragDelta(object sender, DragDeltaEventArgs e)
    {
        DependencyObject parent = sender as DependencyObject;

        try
        {
            do
            {
                parent = VisualTreeHelper.GetParent(parent as DependencyObject);
            } while (parent.GetType() != typeof(Canvas));

            Canvas canvas = parent as Canvas;
            if (canvas.ActualWidth + e.HorizontalChange < canvas.MinWidth)
            {
                e.Handled = true;
            }
        }
        catch
        {
        }
    }

这是我找到工作的唯一方法。希望有更简单的方法。

于 2013-10-02T20:47:06.903 回答
2

我想对所有列应用 minwidth,所以我写了这个:

  public static class GridViewConstraints
  {
    public static readonly DependencyProperty MinColumnWidthProperty =
        DependencyProperty.RegisterAttached("MinColumnWidth", typeof(double), typeof(GridViewConstraints), new PropertyMetadata(75d, (s,e) =>
        {
            if(s is ListView listView)
            {
                listView.Loaded += (lvs, lve) =>
                {
                    if(listView.View is GridView view)
                    {
                        foreach (var column in view.Columns)
                        {
                            SetMinWidth(listView, column);

                            ((System.ComponentModel.INotifyPropertyChanged)column).PropertyChanged += (cs, ce) =>
                            {
                                if (ce.PropertyName == nameof(GridViewColumn.ActualWidth))
                                    SetMinWidth(listView, column);
                            };
                        }
                    }
                };
            }
        }));

    private static void SetMinWidth(ListView listView, GridViewColumn column)
    {
        double minWidth = (double)listView.GetValue(MinColumnWidthProperty);

        if (column.Width < minWidth)
            column.Width = minWidth;
    }

    public static double GetMinColumnWidth(DependencyObject obj) => (double)obj.GetValue(MinColumnWidthProperty);

    public static void SetMinColumnWidth(DependencyObject obj, double value) => obj.SetValue(MinColumnWidthProperty, value);
}

只需将其放在您的列表视图中:

<ListView b:GridViewConstraints.MinColumnWidth="255" />
于 2018-07-19T11:37:32.307 回答
1

如果您想为所有列设置不同的最小宽度并将最大值设置为自动,您可以尝试这个,对于每一列

 <ListView.View>
    <GridView >
        <GridViewColumn Header="FILE NAME" DisplayMemberBinding="{Binding fileName}" Width="auto" >
            <GridViewColumn.HeaderContainerStyle>
                <Style TargetType="{x:Type GridViewColumnHeader}">
                    <Setter Property="MinWidth" Value="200" />

                </Style>
            </GridViewColumn.HeaderContainerStyle>
        </GridViewColumn>
                <GridViewColumn Header="ERROR DETAILS" DisplayMemberBinding="{Binding errorMessage}" Width="auto">
            <GridViewColumn.HeaderContainerStyle>
                <Style TargetType="{x:Type GridViewColumnHeader}">
                    <Setter Property="MinWidth" Value="396" />

                </Style>
            </GridViewColumn.HeaderContainerStyle>
        </GridViewColumn>

    </GridView>
</ListView.View>
于 2021-05-03T06:47:23.733 回答
0

更新比利·杰克·奥康纳 ( Billy Jake O'Connor ) 的解决方案,他提供了最简单、易于实施和工作正确的解决方案。

对于不希望所有列共享相同最小宽度的人,通过下一次代码更新,您可以为每列设置特定的最小宽度,直接在列属性中指定最小宽度。

public static class GridColumn {
    public static readonly DependencyProperty MinWidthProperty =
        DependencyProperty.RegisterAttached("MinWidth", typeof(double), typeof(GridColumn), new PropertyMetadata(75d, (s, e) => {
            if(s is GridViewColumn gridColumn ) {
                SetMinWidth(gridColumn);
                ((System.ComponentModel.INotifyPropertyChanged)gridColumn).PropertyChanged += (cs, ce) => {
                    if(ce.PropertyName == nameof(GridViewColumn.ActualWidth)) {
                        SetMinWidth(gridColumn);
                    }
                };
            }
        }));

    private static void SetMinWidth(GridViewColumn column) {
        double minWidth = (double)column.GetValue(MinWidthProperty);

        if(column.Width < minWidth)
            column.Width = minWidth;
    }

    public static double GetMinWidth(DependencyObject obj) => (double)obj.GetValue(MinWidthProperty);

    public static void SetMinWidth(DependencyObject obj, double value) => obj.SetValue(MinWidthProperty, value);
}

XAML 可能是这样的(“本地”是您使用的命名空间名称,请进行相应修改)

<ListView>
    <ListView.View>
        <GridView>
            <GridViewColumn local:GridColumn.MinWidth="25" />
            <GridViewColumn local:GridColumn.MinWidth="100" />
            <GridViewColumn local:GridColumn.MinWidth="200" />
        </GridView>
    </ListView.View>
</ListView>
于 2020-04-28T07:59:01.440 回答