优化更新代码,添加界面功能并整合

This commit is contained in:
GG Z
2025-02-10 20:53:40 +08:00
parent 83b846f15f
commit 978e03a67f
1389 changed files with 95739 additions and 22200 deletions

View File

@@ -0,0 +1,99 @@
namespace WPFluent.Controls;
/// <summary>
/// Extends <see cref="System.Windows.Controls.ListView"/>, and adds customized support <see
/// cref="ListViewViewState.GridView"/> or <see cref="ListViewViewState.Default"/>.
/// </summary>
/// <example>
/// <code lang="xml"> /// &lt;ui:ListView ItemsSource="{Binding ...}" &gt; /// &lt;ui:ListView.View&gt; ///
/// &lt;ui:GridView&gt; /// &lt;GridViewColumn /// DisplayMemberBinding="{Binding
/// FirstName}" /// Header="First Name" /&gt; /// &lt;GridViewColumn ///
/// DisplayMemberBinding="{Binding LastName}" /// Header="Last Name" /&gt; ///
/// &lt;/ui:GridView&gt; /// &lt;/ui:ListView.View&gt; /// &lt;/ui:ListView&gt; ///</code>
/// </example>
public class ListView : System.Windows.Controls.ListView
{
/// <summary>
/// Identifies the <see cref="ViewState"/> dependency property.
/// </summary>
public static readonly DependencyProperty ViewStateProperty = DependencyProperty.Register(
nameof(ViewState),
typeof(ListViewViewState),
typeof(ListView),
new FrameworkPropertyMetadata(ListViewViewState.Default, OnViewStateChanged));
private DependencyPropertyDescriptor? _descriptor;
static ListView()
{ DefaultStyleKeyProperty.OverrideMetadata(typeof(ListView), new FrameworkPropertyMetadata(typeof(ListView))); }
public ListView()
{
Loaded += OnLoaded;
Unloaded += OnUnloaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Loaded -= OnLoaded; // prevent memory leaks
// Setup initial ViewState and hook into View property changes
_descriptor = DependencyPropertyDescriptor.FromProperty(
System.Windows.Controls.ListView.ViewProperty,
typeof(System.Windows.Controls.ListView));
_descriptor?.AddValueChanged(this, OnViewPropertyChanged);
UpdateViewState(); // set the initial state
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
Unloaded -= OnUnloaded;
_descriptor?.RemoveValueChanged(this, OnViewPropertyChanged);
}
private void OnViewPropertyChanged(object? sender, EventArgs e) { UpdateViewState(); }
private static void OnViewStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if(d is not ListView self)
{
return;
}
self.OnViewStateChanged(e);
}
private void UpdateViewState()
{
ListViewViewState viewState = View switch
{
System.Windows.Controls.GridView => ListViewViewState.GridView,
null => ListViewViewState.Default,
_ => ListViewViewState.Default,
};
SetCurrentValue(ViewStateProperty, viewState);
}
protected override DependencyObject GetContainerForItemOverride() { return new ListViewItem(); }
protected override bool IsItemItsOwnContainerOverride(object item) { return item is ListViewItem; }
protected virtual void OnViewStateChanged(DependencyPropertyChangedEventArgs e)
{
// Hook for derived classes to react to ViewState property changes
}
/// <summary>
/// Gets or sets the view state of the <see cref="ListView"/>, enabling custom logic based on the current view.
/// </summary>
/// <value>The current view state of the <see cref="ListView"/>.</value>
public ListViewViewState ViewState
{
get => (ListViewViewState)GetValue(ViewStateProperty);
set => SetValue(ViewStateProperty, value);
}
}

View File

@@ -0,0 +1,169 @@
<!--
This Source Code Form is subject to the terms of the MIT License.
If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
Copyright (C) Leszek Pomianowski and WPF UI Contributors.
All Rights Reserved.
-->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:WPFluent.Controls">
<ControlTemplate x:Key="NullViewTemplate" TargetType="{x:Type controls:ListView}">
<Grid>
<controls:PassiveScrollViewer
x:Name="PART_ContentHost"
CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
<ItemsPresenter />
</controls:PassiveScrollViewer>
<Rectangle
x:Name="PART_DisabledVisual"
Opacity="0"
RadiusX="2"
RadiusY="2"
Stretch="Fill"
Stroke="Transparent"
StrokeThickness="0"
Visibility="Collapsed">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource ControlFillColorDefault}" />
</Rectangle.Fill>
</Rectangle>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="PART_DisabledVisual" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="GridViewScrollViewerTemplate" TargetType="ScrollViewer">
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel Margin="{TemplateBinding Control.Padding}">
<ScrollViewer
DockPanel.Dock="Top"
Focusable="False"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
<!-- margin-left matched to listviewitem.padding -->
<controls:GridViewHeaderRowPresenter
Margin="4"
AllowsColumnReorder="{Binding Path=View.AllowsColumnReorder, RelativeSource={RelativeSource AncestorType=ListView}}"
ColumnHeaderContainerStyle="{Binding Path=View.ColumnHeaderContainerStyle, RelativeSource={RelativeSource AncestorType=ListView}}"
ColumnHeaderContextMenu="{Binding Path=View.ColumnHeaderContextMenu, RelativeSource={RelativeSource AncestorType=ListView}}"
ColumnHeaderTemplate="{Binding Path=View.ColumnHeaderTemplate, RelativeSource={RelativeSource AncestorType=ListView}}"
ColumnHeaderToolTip="{Binding Path=View.ColumnHeaderToolTip, RelativeSource={RelativeSource AncestorType=ListView}}"
Columns="{Binding Path=View.Columns, RelativeSource={RelativeSource AncestorType=ListView}}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
<ScrollContentPresenter
Name="PART_ScrollContentPresenter"
CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False"
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
KeyboardNavigation.DirectionalNavigation="Local"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</DockPanel>
<ScrollBar
Name="PART_HorizontalScrollBar"
Grid.Row="1"
Cursor="Arrow"
Maximum="{TemplateBinding ScrollViewer.ScrollableWidth}"
Minimum="0"
Orientation="Horizontal"
Visibility="{TemplateBinding ScrollViewer.ComputedHorizontalScrollBarVisibility}"
Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
<ScrollBar
Name="PART_VerticalScrollBar"
Grid.Column="1"
Cursor="Arrow"
Maximum="{TemplateBinding ScrollViewer.ScrollableHeight}"
Minimum="0"
Orientation="Vertical"
Visibility="{TemplateBinding ScrollViewer.ComputedVerticalScrollBarVisibility}"
Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
<DockPanel
Grid.Row="1"
Grid.Column="1"
LastChildFill="False">
<Rectangle
Width="1"
DockPanel.Dock="Left"
Fill="#FFFFFFFF"
Visibility="{TemplateBinding ScrollViewer.ComputedVerticalScrollBarVisibility}" />
<Rectangle
Height="1"
DockPanel.Dock="Top"
Fill="#FFFFFFFF"
Visibility="{TemplateBinding ScrollViewer.ComputedHorizontalScrollBarVisibility}" />
</DockPanel>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="GridViewTemplate" TargetType="{x:Type controls:ListView}">
<Border
Name="Bd"
Background="Transparent"
BorderBrush="{TemplateBinding Border.BorderBrush}"
BorderThickness="{TemplateBinding Border.BorderThickness}">
<controls:PassiveScrollViewer
Padding="{TemplateBinding Control.Padding}"
CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"
Focusable="False"
Template="{DynamicResource GridViewScrollViewerTemplate}">
<ItemsPresenter />
</controls:PassiveScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="ListViewStyle" TargetType="{x:Type controls:ListView}">
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="VirtualizingPanel.IsVirtualizing" Value="True" />
<Setter Property="VirtualizingPanel.VirtualizationMode" Value="Standard" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ViewState, RelativeSource={RelativeSource Mode=Self}}" Value="{x:Static controls:ListViewViewState.Default}">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing="{TemplateBinding VirtualizingPanel.IsVirtualizing}" VirtualizationMode="{TemplateBinding VirtualizingPanel.VirtualizationMode}" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template" Value="{DynamicResource NullViewTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ViewState, RelativeSource={RelativeSource Mode=Self}}" Value="{x:Static controls:ListViewViewState.GridView}">
<Setter Property="Template" Value="{DynamicResource GridViewTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style BasedOn="{StaticResource ListViewStyle}" TargetType="{x:Type controls:ListView}" />
</ResourceDictionary>

View File

@@ -0,0 +1,8 @@
namespace WPFluent.Controls;
public class ListViewItem : System.Windows.Controls.ListViewItem
{
}

View File

@@ -0,0 +1,112 @@
<!--
This Source Code Form is subject to the terms of the MIT License.
If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
Copyright (C) Leszek Pomianowski and WPF UI Contributors.
All Rights Reserved.
-->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:WPFluent.Controls">
<ControlTemplate x:Key="NullViewItemTemplate" TargetType="{x:Type controls:ListViewItem}">
<Border
x:Name="Border"
Margin="0"
Padding="0"
Background="Transparent"
BorderThickness="1"
CornerRadius="{TemplateBinding Border.CornerRadius}">
<Grid>
<ContentPresenter Margin="{TemplateBinding Padding}" />
<Rectangle
x:Name="ActiveRectangle"
Width="3"
Height="18"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Fill="{DynamicResource ListViewItemPillFillBrush}"
RadiusX="2"
RadiusY="2"
Visibility="Collapsed" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEnabled" Value="True" />
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{DynamicResource ListViewItemBackgroundPointerOver}" />
</MultiTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ActiveRectangle" Property="Visibility" Value="Visible" />
<Setter TargetName="Border" Property="Background" Value="{DynamicResource ListViewItemBackgroundPointerOver}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="GridViewItemTemplate" TargetType="{x:Type controls:ListViewItem}">
<Border
x:Name="Border"
Margin="0"
Padding="0"
Background="Transparent"
BorderBrush="{TemplateBinding Border.BorderBrush}"
BorderThickness="{TemplateBinding Border.BorderThickness}"
CornerRadius="{TemplateBinding Border.CornerRadius}">
<Grid>
<controls:GridViewRowPresenter
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
Columns="{TemplateBinding GridView.ColumnCollection}"
Content="{TemplateBinding ContentControl.Content}" />
<Rectangle
x:Name="ActiveRectangle"
Width="3"
Height="18"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Fill="{DynamicResource ListViewItemPillFillBrush}"
RadiusX="2"
RadiusY="2"
Visibility="Collapsed" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEnabled" Value="True" />
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="Background" Value="{DynamicResource ListViewItemBackgroundPointerOver}" />
</MultiTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ActiveRectangle" Property="Visibility" Value="Visible" />
<Setter TargetName="Border" Property="Background" Value="{DynamicResource ListViewItemBackgroundPointerOver}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="ListViewItemStyle" TargetType="{x:Type controls:ListViewItem}">
<Setter Property="Foreground" Value="{DynamicResource ListViewItemForeground}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Border.CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Margin" Value="0,0,0,2" />
<Setter Property="Padding" Value="4" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ViewState, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" Value="Default">
<Setter Property="Template" Value="{DynamicResource NullViewItemTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ViewState, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" Value="GridView">
<Setter Property="Template" Value="{DynamicResource GridViewItemTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style BasedOn="{StaticResource ListViewItemStyle}" TargetType="{x:Type controls:ListViewItem}" />
</ResourceDictionary>

View File

@@ -0,0 +1,10 @@
namespace WPFluent.Controls;
public enum ListViewViewState
{
Default,
GridView,
}