WPF ListBox是ListBoxItems的集合。如何添加列表框项、向 ListBox 添加项、从ListBox删除项以及如何将 ListBox 绑定到数据源,可以在网上搜索相关资料。
先演示一下Newbeecoder.UI列表框运行效果:
这里讨论如何设计和Newbeecoder.UI统一风格样式。对于ListBox容器部分添加几项依赖属性,分别是非客户区鼠标/触摸响应事件、圆角和禁用时鼠标的样式。代码如下:
同样的ListBoxItem的集合类也需要添加自己依赖属性,分别是非客户区鼠标/触摸响应事件、遮罩层背景色、圆角和禁用时鼠标的样式。
类的代码设计完成。但是XAML文件样式也要重新设计。先讲解下ListBox的样式代码:
<Style TargetType="{x:Type local:NbListBox}">
<Setter Property="Background" Value="{Binding Path=Color.Brush_Base1, Source={x:Static local:NbTheme.Current}}" />
<Setter Property="BorderBrush" Value="{Binding Path=Color.Brush_Border3, Source={x:Static local:NbTheme.Current}}" />
<Setter Property="CornerRadius" Value="{Binding Path=Size.CornerRadius, Source={x:Static local:NbTheme.Current}}" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="0" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:NbListBox}">
<Border x:Name="Bd"
SnapsToDevicePixels="True"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}">
<Border.OpacityMask>
<VisualBrush>
<VisualBrush.Visual>
<Border Background="#FFFFFF"
CornerRadius="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CornerRadius}"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}" />
</VisualBrush.Visual>
</VisualBrush>
</Border.OpacityMask>
<ScrollViewer Focusable="False" Padding="{TemplateBinding Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.6" />
</Trigger>
</Style.Triggers>
</Style>
设置水平内容左对齐,垂直内容中间对齐方式,Padding和ListBoxItem内边距,ScrollViewer.VerticalScrollBarVisibility设置垂直滚动条自动显示,当ListBoxItem填充满以后就会显示垂直滚动条。
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="0" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
我给每个ListBoxItem的Border设置为,上、左、右的厚度为0,下方的厚度为1,这样的效果是把ListBoxItem分隔开来,但是我发现他们之间的分割线,居然不一样厚,有点模糊,不是点阵的线,而是有那种抗锯齿的感觉,很不爽。
后来发现Border有SnapsToDevicePixels这么个属性,看名字感觉或许有效果,把它打勾之后,它的作用是使像素与显示器对齐,类似点阵效果。
给Border边框添加Border.OpacityMask不透明画刷。
<Border x:Name="Bd"
SnapsToDevicePixels="True"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}">
<Border.OpacityMask>
<VisualBrush>
<VisualBrush.Visual>
<Border Background="#FFFFFF"
CornerRadius="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CornerRadius}"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}" />
</VisualBrush.Visual>
</VisualBrush>
</Border.OpacityMask>
<ScrollViewer Focusable="False" Padding="{TemplateBinding Padding}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
ListBox的XAML样式就简单实现了,但ListBoxItem也要重写。
这里重点讲一下鼠标放入和选中属性设置:
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.6" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding Path=Color.Brush_Brand1, Source={x:Static local:NbTheme.Current}}" />
<Setter Property="MaskBackground" Value="{Binding Path=Color.Brush_Base1_OP7, Source={x:Static local:NbTheme.Current}}" />
<Setter Property="Foreground" Value="{Binding Path=Color.Brush_Base1, Source={x:Static local:NbTheme.Current}}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{Binding Path=Color.Brush_Brand1, Source={x:Static local:NbTheme.Current}}" />
<Setter Property="MaskBackground" Value="{Binding Path=Color.Brush_Base1_OP5, Source={x:Static local:NbTheme.Current}}" />
<Setter Property="Foreground" Value="{Binding Path=Color.Brush_Base1, Source={x:Static local:NbTheme.Current}}" />
</Trigger>
</Style.Triggers>
当IsMouseOver和IsSelected时,背景色设置成Brush_Brand1主题颜色,MaskBackground遮罩层背景色是Brush_Base1_OP7或Brush_Base1_OP5。
最后调用列表框代码如下:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<TextBlock Text="默认" Margin="5"/>
<NbListBox Style="{DynamicResource DefaultListBoxStyle}" Width="120" Background="{Binding Path=Color.Brush_Border4, Source={x:Static NbTheme.Current}}">
<NbListBoxItem Style="{DynamicResource DefaultListBoxItemStyle}" Content="功能一"/>
<NbListBoxItem Style="{DynamicResource DefaultListBoxItemStyle}" Content="功能二"/>
<NbListBoxItem Style="{DynamicResource DefaultListBoxItemStyle}" Content="功能三"/>
</NbListBox>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Vertical" HorizontalAlignment="Left" Width="120" Margin="30,0,0,0">
<TextBlock Text="菜单" Margin="5"/>
<NbListBox Style="{DynamicResource MenuListBoxStyle}" Background="{Binding Path=Color.Brush_Border4, Source={x:Static NbTheme.Current}}">
<NbListBoxItem Style="{DynamicResource MenuListBoxItemStyle}">
<StackPanel Orientation="Horizontal">
<NbIcon Data="{StaticResource Icon-Button-Fill}" Width="18" Margin="16,0,5,0" Foreground="{Binding Path=Color.Brush_Base2_OP8, Source={x:Static NbTheme.Current}}"/>
<TextBlock Text="按钮" VerticalAlignment="Center"/>
</StackPanel>
</NbListBoxItem>
<NbListBoxItem Style="{DynamicResource MenuListBoxItemStyle}">
<StackPanel Orientation="Horizontal">
<NbIcon Data="{StaticResource Icon-Check-Fill}" Width="18" Margin="16,0,5,0" Foreground="{Binding Path=Color.Brush_Base2_OP8, Source={x:Static NbTheme.Current}}"/>
<TextBlock Text="单选框" VerticalAlignment="Center"/>
</StackPanel>
</NbListBoxItem>
<NbListBoxItem Style="{DynamicResource MenuListBoxItemStyle}">
<StackPanel Orientation="Horizontal">
<NbIcon Data="{StaticResource Icon-Radio-Fill}" Width="18" Margin="16,0,5,0" Foreground="{Binding Path=Color.Brush_Base2_OP8, Source={x:Static NbTheme.Current}}"/>
<TextBlock Text="多选框" VerticalAlignment="Center"/>
</StackPanel>
</NbListBoxItem>
<NbListBoxItem Style="{DynamicResource MenuListBoxItemStyle}">
<StackPanel Orientation="Horizontal">
<NbIcon Data="{StaticResource Icon-ListBox-Fill}" Width="18" Margin="16,0,5,0" Foreground="{Binding Path=Color.Brush_Base2_OP8, Source={x:Static NbTheme.Current}}"/>
<TextBlock Text="列表框" VerticalAlignment="Center"/>
</StackPanel>
</NbListBoxItem>
<NbListBoxItem Style="{DynamicResource MenuListBoxItemStyle}">
<StackPanel Orientation="Horizontal">
<NbIcon Data="{StaticResource Icon-TextBox-Fill}" Width="18" Margin="16,0,5,0" Foreground="{Binding Path=Color.Brush_Base2_OP8, Source={x:Static NbTheme.Current}}"/>
<TextBlock Text="输入框" VerticalAlignment="Center"/>
</StackPanel>
</NbListBoxItem>
</NbListBox>
</StackPanel>
</StackPanel>
需要使用Newbeecoder.UI开源控件库或者定制WPF UI开发请私信给我。