WPF自定义控件10:FlatListView

举报
jackwangcumt 发表于 2021/09/25 10:24:22 2021/09/25
【摘要】 在不少的应用程序中,有时候需要使用ListView控件来显示一组集合数据,这样可以从一组数据中进行选择,让数据更加的规范,便于统计和分析。本文将介绍一下自定义的列表控件FlatListView,它与FlatCheckBox实现过程非常类似,它是继承自ListView,但使用自定义的UI样式来美化界面。

      在不少的应用程序中,有时候需要使用ListView控件来显示一组集合数据,这样可以从一组数据中进行选择,让数据更加的规范,便于统计和分析。本文将介绍一下自定义的列表控件FlatListView,它与FlatCheckBox实现过程非常类似,它是继承自ListView,但使用自定义的UI样式来美化界面。下面将详细介绍具体的实现细节。

1 WPF项目结构


    基于之前创建的WPF示例项目,在其中创建一个新的关于FlatListView的项目文件。本质上,FlatListView是继承ListView控件,利用ListView控件自身的属性和方法,可以减少FlatListView实现的难度和复杂度。首先,给出本项目文件结构,如下图所示:

1.jpg

其中的Fonts目录下存放各种图标字体文件,Style目录下存放各种控件的UI 样式定义文件,FlatListView.xaml就是FlatListView控件的样式定义文件。另外,需要将其注册到Generic.xaml文件中,示例代码如下:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Yd.WpfControls">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/Yd.WpfControls;component/Style/IconFont.xaml"/>
        <ResourceDictionary Source="/Yd.WpfControls;component/Style/FlatButton.xaml"/>
        <ResourceDictionary Source="/Yd.WpfControls;component/Style/FlatCheckBox.xaml"/>
        <ResourceDictionary Source="/Yd.WpfControls;component/Style/FlatRadioButton.xaml"/>
        <ResourceDictionary Source="/Yd.WpfControls;component/Style/ToggleButton.xaml"/>
        <ResourceDictionary Source="/Yd.WpfControls;component/Style/FlatComboBox.xaml"/>
        <ResourceDictionary Source="/Yd.WpfControls;component/Style/FlatTextBox.xaml"/>
        <ResourceDictionary Source="/Yd.WpfControls;component/Style/FlatListView.xaml"/>
    </ResourceDictionary.MergedDictionaries>

</ResourceDictionary>

2 WPF FlatListView实现


    首先在Yd.WpfControls项目中添加一个类FlatListView.cs,它继承自ListView控件,示例代码如下:

using System.Windows;
using System.Windows.Controls;
namespace Yd.WpfControls
{
    public class FlatListView : ListView
    {
        static FlatListView()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(FlatListView),
                new FrameworkPropertyMetadata(typeof(FlatListView)));
        }
    }
}

FlatListView控件的UI样式主要就是依靠FlatListView.xaml文件进行定义的,示例代码如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                   xmlns:local="clr-namespace:Yd.WpfControls">
    <!--图标字体引入-->
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary  Source="/Yd.WpfControls;component/Style/IconFont.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <SolidColorBrush x:Key="ListBox.Static.Background" Color="#34495e"/>
    <SolidColorBrush x:Key="ListBox.Static.Border" Color="#34495e"/>
    <SolidColorBrush x:Key="ListBox.Disabled.Background" Color="#FFFFFFFF"/>
    <SolidColorBrush x:Key="ListBox.Disabled.Border" Color="#FFD9D9D9"/>
    
    <Style x:Key="Flat_ListViewStyle" TargetType="{x:Type ListView}">
        <Setter Property="Background" Value="{StaticResource ListBox.Static.Background}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ListBox.Static.Border}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
        <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListView}">
                    <Border x:Name="Bd" Background="{TemplateBinding Background}" 
                                BorderThickness="{TemplateBinding BorderThickness}" 
                                BorderBrush="{TemplateBinding BorderBrush}" 
                                Padding="1" SnapsToDevicePixels="true">
                        <ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Background" TargetName="Bd" Value="{StaticResource ListBox.Disabled.Background}"/>
                            <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ListBox.Disabled.Border}"/>
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsGrouping" Value="true"/>
                                <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="Flat_ItemHover" TargetType="{x:Type ListViewItem}">
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="Height" Value="30" />
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="true">
                <Setter Property="Background" Value="#2ecc71" />
                <Setter Property="Foreground" Value="Orange" />
                <Setter Property="Cursor" Value="Hand" />
            </Trigger>
            <Trigger Property="IsSelected" Value="true">
                <Setter Property="Background" Value="#2ecc71" />
                <Setter Property="Foreground" Value="Yellow" />
                <!--<Setter Property="FontWeight" Value="Bold" />-->
                <Setter Property="Cursor" Value="Hand" />
            </Trigger>
        </Style.Triggers>
    </Style>

    <Style TargetType="{x:Type local:FlatListView}" BasedOn="{StaticResource Flat_ListViewStyle}" >
        <Setter Property="FontSize" Value="{x:Static local:FlatFonts.contentFontSize}"></Setter>
        <Setter Property="Foreground" Value="White"></Setter>
        <!-- Item Container样式 -->
        <Setter Property="ItemContainerStyle"  Value="{StaticResource Flat_ItemHover}"></Setter>
        <Setter Property="Cursor" Value="Hand"/>
    </Style>

</ResourceDictionary>

   其中<Style TargetType="{x:Type local:FlatListView}" BasedOn="{StaticResource Flat_ListViewStyle}" 语句中的BasedOn表示继承关系,即一个新的Style可以通过BasedOn来继承,这样就可以更加方便的管理样式。另外,ListView每个Item容器的样式是通过ItemContainerStyle实现的,即 <Setter Property="ItemContainerStyle"  Value="{StaticResource Flat_ItemHover}"></Setter>  。

3 WPF FlatListView测试


    首先,需要重新生成一下项目文件,然后在WpfControls项目中添加Window8窗口,并添加自定义控件FlatListView,Window8.xaml示例代码如下:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfControls"
        xmlns:WpfControls="clr-namespace:Yd.WpfControls;assembly=Yd.WpfControls" x:Class="WpfControls.Window8"
        mc:Ignorable="d"
        Title="Window8" Height="350" Width="500">
    <Grid>

        <WpfControls:FlatListView Name="flatListView" FontSize="13">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <TextBlock Text="{Binding Name}"  />
                        <TextBlock Text=" (" />
                        <TextBlock Text="{Binding Counter}"  Cursor="Hand"/>
                        <TextBlock Text=")" />
                    </WrapPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </WpfControls:FlatListView>

    </Grid>
</Window>

其中的Name="flatListView"给控件起一个名称,这样可以在后台用C#来进行访问,下面给出后台初始化数据的示例代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfControls
{
    /// <summary>
    /// Window8.xaml 的交互逻辑
    /// </summary>
    public partial class Window8 : Window
    {
        public Window8()
        {
            InitializeComponent();

            List<Classz> items = new List<Classz>();
            items.Add(new Classz() { Name = "Java语言编程", Counter = 42 });
            items.Add(new Classz() { Name = "数据结构C++", Counter = 39 });
            items.Add(new Classz() { Name = "FSharp编程基础", Counter = 13 });
            flatListView.ItemsSource = items;
        }

        public class Classz
        {
            public string Name { get; set; }
            public int Counter { get; set; }
        }
    }
}

运行界面如下:

6.jpg

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。