【发布时间】:2021-06-03 11:11:14
【问题描述】:
我试图在 .NET WPF 中创建 ListView 的扩展版本。 我有更多的模板和样式,然后是我想要实现的,但为了测试目的而将其剥离。即使这两个似乎也无法工作或加载,因为没有显示任何已配置的内容。
现在对我来说奇怪的是,这些在放入用户控件时工作,使用常规 ListView 并使用相同类型的 StaticResource 引用。
然而,我认为可以将它们放在一个共享的 xaml 和 cs 文件中以获得更好的可重用性。
我是否为指定类型的 ListView 设置了错误?
XAML
<ListView x:Class="MyProject.SharedView.ExtListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<ListView.Resources>
<Style x:Key="ArColumnHeaderContainerStyle" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Control.HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Control.VerticalContentAlignment" Value="Center" />
<Setter Property="Control.Background" Value="Gray" />
</Style>
<DataTemplate x:Key="ArColumnHeaderTemplate">
<StackPanel Orientation="Vertical" VerticalAlignment="Top" HorizontalAlignment="Stretch">
<DockPanel Name="dpQColHead" Grid.Row="0">
<CheckBox/>
<TextBlock Foreground="Red" TextTrimming="None" TextWrapping="Wrap">
<TextBlock.Text>
<Binding />
</TextBlock.Text>
</TextBlock>
</DockPanel>
</StackPanel>
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView
ColumnHeaderTemplate="{StaticResource ArColumnHeaderTemplate}"
ColumnHeaderContainerStyle="{StaticResource ArColumnHeaderContainerStyle}">
</GridView>
</ListView.View>
CS
public partial class ExtListView : ListView
{
public ExtListView()
{
InitializeComponent();
this.AddHandler(
GridViewColumnHeader.ClickEvent,
new RoutedEventHandler(GridViewColumnHeaderClickedHandler));
}
private GridViewColumnHeader _lastHeaderClicked = null;
private ListSortDirection _lastDirection = ListSortDirection.Ascending;
/// <summary>
/// Sort data
/// </summary>
/// <param name="sortBy"></param>
/// <param name="direction"></param>
private void Sort(string sortBy, ListSortDirection direction)
{
ICollectionView dataView =
CollectionViewSource.GetDefaultView(this.ItemsSource);
if (dataView != null)
{
dataView.SortDescriptions.Clear();
SortDescription sd = new SortDescription(sortBy, direction);
dataView.SortDescriptions.Add(sd);
dataView.Refresh();
}
}
/// <summary>
/// Event, Grid column header clicked
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
{
GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
ListSortDirection direction;
if (headerClicked != null &&
headerClicked.Role != GridViewColumnHeaderRole.Padding)
{
if (_lastHeaderClicked != null)
{
ColumnAdorner.RemoveAdorner(_lastHeaderClicked);
}
if (headerClicked != _lastHeaderClicked)
{
direction = ListSortDirection.Ascending;
}
else
{
if (_lastDirection == ListSortDirection.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
direction = ListSortDirection.Ascending;
}
}
// see if we have an attached SortPropertyName value
string sortBy = GetSortPropertyName(headerClicked.Column);
if (string.IsNullOrEmpty(sortBy))
{
// otherwise use the column header name
sortBy = headerClicked.Column.Header as string;
}
Sort(sortBy, direction);
_lastHeaderClicked = headerClicked;
_lastDirection = direction;
ColumnAdorner.SetAdorner(headerClicked, direction);
}
}
/// <summary>
/// Custom sorting property
/// </summary>
public static readonly DependencyProperty SortPropertyNameProperty =
DependencyProperty.RegisterAttached("SortPropertyName", typeof(string), typeof(AriesListView));
/// <summary>
/// Gets property
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string GetSortPropertyName(GridViewColumn obj)
{
return (string)obj.GetValue(SortPropertyNameProperty);
}
/// <summary>
/// Set property name
/// </summary>
/// <param name="obj"></param>
/// <param name="value"></param>
public static void SetSortPropertyName(GridViewColumn obj, string value)
{
obj.SetValue(SortPropertyNameProperty, value);
}
}
运行自定义 ListView
...
<sv:ArListView
BorderBrush="#b7d9ed" BorderThickness="1"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
Grid.Row="1" Margin="4,4,0,0"
ItemsSource="{Binding Path=TargetObject.AssignedClassification.ExternalStandardMappings}"
GridViewColumnHeader.Click="SortGridViewByColumn">
<sv:ArListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=Standard.Name}" Header="Standard" Width="100"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=ID}" Header="ID" Width="Auto"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=Description}" Header="Description" Width="Auto"/>
</GridView>
</sv:ArListView.View>
</sv:ArListView>
...
【问题讨论】:
-
ExtListView.xaml.cs是如何定义的以及您如何测试/使用ListView? -
已经更新了帖子,包括后面的代码以及它是如何包含在另一个用户控件中的。
-
究竟什么是“不工作”?会发生什么,您预计会发生什么?
-
ArColumnHeaderTemplate未被使用。没有红色文本,也没有显示复选框。 -
那是因为您在
UserControl中将View属性设置为完全不同的GridView。