ItemsControl不支持列表选择。
ListBox继承于ItemsControl,多一个Selector对象,支持单选和多选。
ListView继承于ListBox,多一个View对象。
2022/12/8更新:固定宽度的GridViewColumn
ListView的列宽是可以通过拖动改变的,但是我希望某个列的宽度固定。
/// <summary>
/// 固定宽度的ListView列
/// </summary>
public class FixedWidthColumn : GridViewColumn
{
static FixedWidthColumn()
{
WidthProperty.OverrideMetadata(typeof(FixedWidthColumn),
new FrameworkPropertyMetadata(null, new CoerceValueCallback(OnCoerceWidth)));
}
public double FixedWidth
{
get { return (double)GetValue(FixedWidthProperty); }
set { SetValue(FixedWidthProperty, value); }
}
public static readonly DependencyProperty FixedWidthProperty =
DependencyProperty.Register(
"FixedWidth",
typeof(double),
typeof(FixedWidthColumn),
new FrameworkPropertyMetadata(double.NaN, new PropertyChangedCallback(OnFixedWidthChanged)));
private static void OnFixedWidthChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
FixedWidthColumn fwc = o as FixedWidthColumn;
if (fwc != null)
fwc.CoerceValue(WidthProperty);
}
private static object OnCoerceWidth(DependencyObject o, object baseValue)
{
FixedWidthColumn fwc = o as FixedWidthColumn;
if (fwc != null)
return fwc.FixedWidth;
return baseValue;
}
}
使用时,直接在原本放GridViewColumn的位置,放:
<local:FixedWidthColumn x:Name="FixedWidthColumn"/>
此时就添加了FixedWidth属性,跟Width一样用就可以。
举例应用场景:某个ListView占据整个窗口,当窗口的宽度发生改变时,某一列中显示的字符个数根据窗口宽度变化。
笔记在这里:https://blog.csdn.net/pxy7896/article/details/128233934
2021/8/4 更新:根据index查找数据对象和控件对象
查找数据对象
前台
<ListView Grid.Row="1" x:Name="listSeq"/>
后台
ItemCollection objects = this.listSeq.Items; // 得到的是数据源类型的集合
objects.GetItemAt(index); // 取对象
查找控件对象
前台照旧,后台这样写,可以得到指定index下ListView项中的控件对象
ListViewItem listViewItem = this.listSeq.ItemContainerGenerator.ContainerFromIndex(index) as ListViewItem;
List<TextBox> t = WpfTools.GetChildrenObjects<TextBox>(listViewItem);
GetChildrenObjects()函数参考:wpf-查找指定类型的父元素/子元素
2021/7/26更新:表头header的调整
我想把header的内容放居左,不要按默认的居中。GridViewColumn.Header里是可以放控件的,不一定要文字。
header的hover和focus效果是不能通过写这个Style改变的,这似乎是一个bug,没找到解决方案。
<ListView.View>
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="GridViewColumnHeader">
<!-- 让title始终靠左 -->
<Setter Property="HorizontalContentAlignment" Value="Left"/>
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn >
<GridViewColumn.Header>
<!-- 刻度尺,是我自己写的控件 -->
<local:Ruler />
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
...
基础格式
<ListView x:Name="XXXX">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="BorderBrush" Value="DarkSlateGray" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="名称" DisplayMemberBinding="{Binding Name}" Width="150" />
<GridViewColumn Header="位点" DisplayMemberBinding="{Binding Position}" Width="100"/>
<GridViewColumn Header="其他位点" DisplayMemberBinding="{Binding PositionStr}"/>
</GridView>
</ListView.View>
</ListView>
这样的话,每行的内容是不能复制的,所以可以用CellTemplate改写,如下例:
<ListView.View>
<GridView>
<GridViewColumn Header="名称" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Name}" IsReadOnly="True" BorderThickness="0" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
...
</GridView>
</ListView.View>
本来还想把列分隔线搞出来,不过按我下面这种写法,分隔线不能拖动哦!还是贴一下吧。
显然是因为我把它们放到一列里去了(真是十分窒息的操作),header的对齐我也调不了(试过margin了)。
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="名称" IsReadOnly="True" BorderThickness="0" />
<TextBox Grid.Column="1" Text="位点" IsReadOnly="True" BorderThickness="0" />
<TextBox Grid.Column="2" Text="其他位点" IsReadOnly="True" BorderThickness="0"/>
<Border BorderBrush="Gray" Grid.Column="1" Grid.ColumnSpan="1" BorderThickness="1,0,1,0"/>
</Grid>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Name}" IsReadOnly="True" BorderThickness="0" />
<TextBox Grid.Column="1" Text="{Binding Position}" IsReadOnly="True" BorderThickness="0" />
<TextBox Grid.Column="2" Text="{Binding PositionStr}" IsReadOnly="True" BorderThickness="0"/>
<Border BorderBrush="Gray" Grid.Column="1" Grid.ColumnSpan="1" BorderThickness="1,0,1,0"/>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
为每行加框线
在ListView标签下加下面的代码:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="BorderBrush" Value="DarkSlateGray" />
</Style>
</ListView.ItemContainerStyle>
为每列设置不同的格式
<ListView.View>
<GridView>
<GridViewColumn Header="名称">
<GridViewColumn.CellTemplate>
<DataTemplate>
...放Grid/ListView/TextBlock/Image等都可以
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
...依次设置各列的格式
</ListView.View>
颜色列的方块
本来想用checkbox做,但是???我为什么会想到checkbox???直接用Rectangle就可以了。
<Rectangle Height="14" Width="14" Fill="{Binding Color}"
VerticalAlignment="Center" Margin="3"/>