WPF 自定义ItemsControl/ListBox/ListView控件样式
一、前言
ItemsControl、ListBox、ListView这三种控件在WPF中都可作为列表信息展示控件。我们可以通过修改这三个控件的样式来展示我们的列表信息。
既然都是展示列表信息的控件,那他们有什么相同点和不同点呢。
同:
1、这三个控件都是列表型控件,可以进行列表绑定(ItemsSource);
2、这三个控件均使用ItemsPresenter来展示列表信息;
异:
1、ListBox继承于ItemsControl,比ItemsControl一个Selector对象;
2、ListView继承于ListBox,比ListBox多一个View属性。
也就是说ItemsControl不支持列表项选择功能,ListBox支持单选、多选。ListView能以不同的视图形式展示列表信息。
下面我们通过例子来展现:
1.1、ItemsControl实现的图片选择预览控件
控件的效果如下:

下面贴上代码:
<StackPanel Orientation="Horizontal" Margin=" 0 0" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid>
<Rectangle x:Name="rectangle" RadiusX="0" RadiusY="0" Width="50" Height="50" MouseLeftButtonUp="UpLoadCaptrue_Click" SnapsToDevicePixels="True" StrokeDashArray="3 3 3 3" StrokeThickness="1" Margin="5 0">
<Rectangle.Fill>
<ImageBrush ImageSource="/Images/UpLoad.png" Opacity="0.3" Stretch="Fill" Viewport="0.25 0.25 0.5 0.5"/>
</Rectangle.Fill>
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Stroke" Value="#999999"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Stroke" Value="#1dc0a5"/>
</Trigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
<ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Hidden" Width="360">
<ItemsControl x:Name="itemsControl" Background="Transparent" ItemsSource="{Binding }">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel>
<Grid Width="60" Height="60" SnapsToDevicePixels="True">
<Border BorderBrush="#999999" Width="50" Height="50" BorderThickness="1" Margin="5 0">
<Image Source="{Binding}" Width="40" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Image Source="/Images/Close.png" Width="16" Height="16" MouseLeftButtonUp="ReMoveCaptrue_Click" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0 2 0 0">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="Red" Opacity="1" BlurRadius="5"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Grid>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
上面ItemsControl设置了ItemsPanel,由于我们的列表展示是横向的,所以设置StackPanel,并将Orientation设置为Horizontal。
里面有两个事件,添加图片UpLoadCaptrue_Click和移除图片ReMoveCaptrue_Click。代码如下:
public MainWindow()
{
InitializeComponent();
this.itemsControl.ItemsSource = Capture;
} public ObservableCollection<string> Capture = new ObservableCollection<string>(); /// <summary>
/// 上传截图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void UpLoadCaptrue_Click(object sender, MouseButtonEventArgs e)
{
OpenFileDialog logoSelected = new OpenFileDialog();
logoSelected.Filter = "图片|*.jpg;*.png;*.bmp;*.gif";
if (logoSelected.ShowDialog() ==true)
{
Capture.Add(logoSelected.FileName);
}
} /// <summary>
/// 移除截图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ReMoveCaptrue_Click(object sender, MouseButtonEventArgs e)
{
Capture.Remove(((Image)sender).DataContext.ToString());
}
控件中用到的素材:

1.2、基于ListBox实现用户列表展示
下面的实例一般用于通讯软件用户列表展示。主要是通过修改ListBoxItem的样式来实现。
先看下实现的效果:

大体思路:先定义ListBoxStyle,定义ListBox的Style是为了实现去掉列表项的间隙,默认的ListBox里面有Padding值。我们把Padding改为0;然后定义ListBoxItem项的Style样式,因为我们是通过绑定数据的方式呈现,因此对于需要动态显示的值我们把它放到一个类中。
public List<UserInfo> UserList { get; set; }
public class UserInfo
{
public Brush UserBackground { get; set; }
public string Header { get; set; }
public string Name { get; set; }
public string Info { get; set; }
public int Count { get; set; }
}
ListBoxItem样式代码如下:
<Style x:Key="UserInfoStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid Height="50" x:Name="grid">
<Border Background="{Binding UserBackground}" Width="40" Height="40" CornerRadius="4" HorizontalAlignment="Left" Margin="5 0 0 0">
<TextBlock Text="{Binding Header}" FontSize="23" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<TextBlock Text="{Binding Name}" Margin="55 7 0 0" FontSize="13"/>
<TextBlock Text="{Binding Info}" Foreground="#808080" Margin="55 30 0 0"/>
<TextBlock Text="{Binding Count,StringFormat={}{0}人}" Foreground="#808080" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0 0 5 0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="grid" Property="Background" Value="#fceeb9"/>
</Trigger>
<Trigger Property="Selector.IsSelected" Value="true">
<Setter TargetName="grid" Property="Background" Value="#fae388"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ListBox样式代码如下:
<ListBox BorderThickness="1" ItemContainerStyle="{StaticResource UserInfoStyle}" x:Name="UserInfoList" BorderBrush="#eaeaeb" Background="Transparent" Width="280" Height="300" Margin="50 5 0 0">
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="0">
<ScrollViewer Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
</ListBox>
后台C#代码初始化数据,及设定数据源:
UserList = new List<UserInfo>()
{
new UserInfo(){
UserBackground=new SolidColorBrush((Color)ColorConverter.ConvertFromString("#ff9f4c")),
Header="群",
Name="DESKTOP-0N",
Info="我要像风一样自由!",
Count=
},
new UserInfo(){
UserBackground=new SolidColorBrush((Color)ColorConverter.ConvertFromString("#ff9f4c")),
Header="张",
Name="张三丰",
Info="我要像风一样自由!",
Count=
},
new UserInfo(){
UserBackground=new SolidColorBrush((Color)ColorConverter.ConvertFromString("#9d9d9d")),
Header="鬼",
Name="鬼见愁",
Info="我要像风一样自由!",
Count=
},
};
this.UserInfoList.ItemsSource = UserList;
1.3、ListBoxView列表信息展示
ListBoxView信息展示有点像DataGrid控件,以下为ListBoxView基本样式代码:
<Style x:Key="ListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<GridViewRowPresenter VerticalAlignment="Center" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" TargetName="Bd" Value="#FF866C"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="Bd" Value="#FFEAE4"></Setter>
<Setter Property="Foreground" Value="Black"></Setter>
</Trigger>
<Trigger Property="Height" Value="Auto">
<Setter Property="MinHeight" Value="35" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListViewStyle1" TargetType="{x:Type ListView}">
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"></Setter>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource ListViewItemStyle}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListView}">
<ScrollViewer Padding="{TemplateBinding Padding}" Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
<ControlTemplate.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="GridViewColumnHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Background" Value="#FFEAE4" />
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
<Grid SnapsToDevicePixels="True" >
<Border x:Name="HeaderBorder" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition MaxHeight="7"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Padding="{TemplateBinding Padding}" Grid.RowSpan="2">
<ContentPresenter x:Name="HeaderContent" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</Border>
<Canvas>
<Thumb x:Name="PART_HeaderGripper">
<Thumb.Style>
<Style TargetType="{x:Type Thumb}">
<Setter Property="Canvas.Right" Value="-9"/>
<Setter Property="Width" Value="18"/>
<Setter Property="Height" Value="{Binding ActualHeight, RelativeSource={RelativeSource TemplatedParent}}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="Transparent" Padding="{TemplateBinding Padding}">
<Rectangle Fill="{TemplateBinding Background}" HorizontalAlignment="Center" Width="1"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Thumb.Style>
</Thumb>
</Canvas>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="HeaderBorder" Value="#FF866B"/>
<Setter Property="Background" TargetName="PART_HeaderGripper" Value="Transparent"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="HeaderBorder" Value="#FF866B"/>
<Setter Property="Visibility" TargetName="PART_HeaderGripper" Value="Hidden"/>
</Trigger>
<Trigger Property="Height" Value="Auto">
<Setter Property="MinHeight" Value="35"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
引用示例:
<ListView x:Name="ListView" Style="{StaticResource ListViewStyle1}" Width="500">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource GridViewColumnHeaderStyle}">
<GridViewColumn Header="序号" DisplayMemberBinding="{Binding Num}" Width="100"/>
<GridViewColumn Header="名称" DisplayMemberBinding="{Binding Name}" Width="100"/>
<GridViewColumn Header="Template" Width="auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Content="{Binding Template}"></CheckBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
后台代码需要给ListBoxView绑定数据:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ListViewDataList = new List<ListViewData>();
for (int i = ; i < ; i++)
{
ListViewDataList.Add(new ListViewData()
{
Num = i,
Name = "No_" + i.ToString(),
Template="Temlate:"+i.ToString()
});
}
this.ListView.ItemsSource = ListViewDataList;
}
public List<ListViewData> ListViewDataList { get; set; }
public class ListViewData
{
public int Num { get; set; }
public string Name { get; set; }
public string Template { get; set; }
} }
效果图:

所有代码已经上传到github:https://github.com/cmfGit/WpfDemo.git
WPF 自定义ItemsControl/ListBox/ListView控件样式的更多相关文章
- 【C#】wpf自定义calendar日期选择控件的样式
原文:[C#]wpf自定义calendar日期选择控件的样式 首先上图看下样式 原理 总览 ItemsControl内容的生成 实现 界面的实现 后台ViewModel的实现 首先上图,看下样式 原理 ...
- WPF自定义LED风格数字显示控件
原文:WPF自定义LED风格数字显示控件 版权声明:本文为博主原创文章,转载请注明作者和出处 https://blog.csdn.net/ZZZWWWPPP11199988899/article/de ...
- FastReport自定义数据源及ListView控件的使用
##1.想批量生成一堆物资信息卡,效果如下图所示,fastreport可以一下全部生成,并且发现不用单独写东西, ##2.发现FastReport官方给出的Demo.exe很友好,基本可以满足要求,想 ...
- WPF 自定义TextBox带水印控件,可设置圆角
一.简单设置水印TextBox控件,废话不多说看代码: <TextBox TextWrapping="Wrap" Margin="10" Height=& ...
- WPF中在后台实现控件样式
加入现在有一个Button的样式如下: <Style TargetType="{x:Type Button}" x:Key="MyButton">. ...
- 初步探讨WPF的ListView控件(涉及模板、查找子控件) - GavinJun
本文结合模板的应用初步介绍ListView的应用 一.Xaml中如何建立数据资源 大部分数据都会来自于后台代码,如何Xaml同样的建立数据源呢?比如建立一个学生List: 首先引入命名空间: xmln ...
- WPF Calendar 日历控件 样式自定义
原文:WPF Calendar 日历控件 样式自定义 粗略的在代码上做了些注释 blend 生成出来的模版 有的时候 会生成 跟 vs ui界面不兼容的代码 会导致可视化设计界面 报错崩溃掉 但是确不 ...
- WPF中Expander控件样式,ListBox的样式(带checkbox)恢复
Expander控件样式: <ControlTemplate x:Key="ExpanderToggleButton" TargetType="ToggleButt ...
- WPF 自定义TabControl控件样式
一.前言 程序中经常会用到TabControl控件,默认的控件样式很普通.而且样式或功能不一定符合我们的要求.比如:我们需要TabControl的标题能够居中.或平均分布:或者我们希望TabContr ...
随机推荐
- HandsonTable日期控件的汉化
由于项目的需要,想把HandsonTable自带的日期中英文替换成中文.其实这个不难,只要在库文件中替换下就可以了,替换的效果对比如下: 如果有需要的同学,可以在此处下载 By QJL
- testng及JMeter使用之初体验
这里只是简单的说下我再项目中使用testng的JMeter使用的情况, 主要的是使用JMeter的体验, 都是以截图和文字为说明的. 1, 性能测试之testng 直接可以 ...
- Eclipse中JRE(unbound)问题的一种解决方法
(如果有写的不对的地方,欢迎指正!) 1.检查Java环境变量配置是否有问题 jdk1.8环境变量配置(1.8和8是一个意思) jdk9环境变量配置 注:配置不成功的一种可能是安装多个jdk,解决方法 ...
- Mac下使用终端连接远程使用ssh协议的git服务器
最近换了台新电脑, MacBook pro,拿到新电脑之后小小心喜了一下(终于解脱windows的束缚拥抱mac啦), 然后就开始苦逼的安装各种开发环境了. 之前在windows上使用tortoise ...
- [Tarjan 学习笔记](无向图)
今天考试因为不会敲 Dcc 的板子导致没有AK(还不是你太菜了),所以特地写一篇博客记录 Tarjan 的各种算法 无向图的割点与桥 (各种定义跳过) 割边判定法则 无向边 (x,y) 是桥,当且仅当 ...
- 获取DOM节点的几种方式
DOM 是一个树形结构,操作一个DOM节点,实际上就是这几个操作:更新.删除.添加.遍历 在操作DOM节点之前,需要通过各种方式先拿到这个DOM节点,常用的方法有: 一.通过元素类型的方法来操作: d ...
- 使用IDEA搭建Spring Boot入门项目
简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置 ...
- 【Python】 多线程并发threading & 任务队列Queue
threading python程序默认是单线程的,也就是说在前一句语句执行完之前后面的语句不能继续执行(不知道我理解得对不对) 先感受一下线程,一般情况下: def testa(): sleep(1 ...
- 智齿客服网页端接入文档V2.3
产品介绍 智齿客服网页端接入提供以下两种部署方式. 一.网页组件(推荐) 通过智齿客服网站咨询组件,企业的用户可快捷联系到企业客服获取帮助.智齿客服网页组件提供强大的用户行为采集能力和系统对接能力,支 ...
- 使用 js 设置组合快捷键,支持多个组合键定义,还支持 React
╭┈┈╮ ╭┈┈╮ ╭┈┈╮ ┆ ├┈┈..┈┈┈┈┈.┆ └┈╮┆ ├┈┈..┈┈┈┈┈..┈┈.┈┈..┈┈┈┈┈. ┆ ┆┆ □ ┆┆ ┈┤┆ < ┆ -__┘┆ ┆ ┆┆__ ┈┈┤ ╰ ...