在回答类似问题here之后,我能够在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>
答案 0 :(得分:5)
<Window.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}" >
<Setter Property="MinWidth" Value="400" />
</Style>
</Window.Resources>
答案 1 :(得分:5)
如果使用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;
}
}
答案 2 :(得分:4)
<ListView>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock MinWidth="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
...more columns...
</GridView>
</ListView.View>
</ListView>
答案 3 :(得分:4)
ListView的标题是GridViewColumnHeader。 下面显示的是GridViewColumnHeader的ControlTemplate的简化版本。我们可以看到,它在Canvas中使用Thumb来创建拖动/调整大小效果。
PS:要获得完整的GridViewColumnHeader ControlTemplate,请参阅How to grab WPF 4.0 control default templates?
<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的大小,我们需要挂钩Thumb的拖动事件(DragStarted,DragDelta,DragCompleted ......等)。
只要我们知道DragDelta内的MinSize,我们所需要的就是DragDeltaEventHandler事件。
下面显示的是带有注释的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:
<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
{
}
}
这是我找到工作的唯一方法。希望有一种更简单的方法。
答案 4 :(得分:2)
我想对所有列应用最小宽度,所以我这样写:
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" />
答案 5 :(得分: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>
答案 6 :(得分: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可能是这样的(“ local”是您使用的名称空间名称,请进行相应修改)
<ListView>
<ListView.View>
<GridView>
<GridViewColumn local:GridColumn.MinWidth="25" />
<GridViewColumn local:GridColumn.MinWidth="100" />
<GridViewColumn local:GridColumn.MinWidth="200" />
</GridView>
</ListView.View>
</ListView>