• C# wpf 使用ListBox实现尺子控件



    前言

    尺子在客户端开发中有一定的应用场景,比如厘米尺、白板的画线尺、视频剪辑的时间尺。一般可以采用用户控件通过自绘的方式实现,但今天我要讲一个不一样的方法,不使用自定义控件也不用用户控件,只需要ListBox即能实现一把尺子。


    一、如何实现?

    1、设置横向ListBox

    我们实现一把水平的尺子,所以需要让ListBox横向显示

    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Horizontal">VirtualizingStackPanel>
        ItemsPanelTemplate>
    ListBox.ItemsPanel>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、Item设为刻度样式

    一个Item就是一个刻度,我们通过ItemTemplate的方式设置样式。

    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Width="10" Height="46" Orientation="Vertical" Background="Transparent">
                <TextBlock x:Name="text" Margin="0,6,0,6" HorizontalAlignment="Center"  FontSize="16"  Text="{Binding Number}" Foreground="#ffffff"  Visibility="{Binding NumberVisibility}">TextBlock>
                <Line x:Name="line"  HorizontalAlignment="Center" Height="20" Width="5" X1="2.5" Y1="0" X2="2.5" Y2="25" StrokeThickness="1" Stroke="#aaaaaa">Line>
            StackPanel>
    ListBox.ItemTemplate>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、绑定数据源

    由于ListBox是基于数据集合来显示控件的,我们通过绑定数据源让其显示刻度。

    <ListBox  ItemsSource="{Binding Chips}">
    
    • 1
    public class RulerChip
    {
        public double Number { get; set; }
        public Visibility NumberVisibility { get; set; }
    
    }
    public List<RulerChip> Chips { get; set; }=new List<RulerChip>();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二、完整代码

    MainWindow.xaml

    <Window x:Class="WpfApp7.MainWindow"
            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:WpfApp7"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <ListBox  Background="#333333" Height="50" ItemsSource="{Binding Chips}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
                <ListBox.ItemContainerStyle>
                    <Style  TargetType="{x:Type ListBoxItem}">
                        "Template">
                            
                                "{x:Type ListBoxItem}">
                                    "{TemplateBinding Content}"
                                                       ContentStringFormat="{TemplateBinding ContentStringFormat}"
                                                       ContentTemplate="{TemplateBinding ContentTemplate}" />
                                
                            
                        
                    Style>
                ListBox.ItemContainerStyle>
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel Orientation="Horizontal">VirtualizingStackPanel>
                    ItemsPanelTemplate>
                ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Width="10" Height="46" Orientation="Vertical" Background="Transparent">
                            <TextBlock x:Name="text" Margin="0,6,0,6" HorizontalAlignment="Center"  FontSize="16"  Text="{Binding Number}" Foreground="#ffffff"  Visibility="{Binding NumberVisibility}">TextBlock>
                            <Line x:Name="line"  HorizontalAlignment="Center" Height="20" Width="5" X1="2.5" Y1="0" X2="2.5" Y2="25" StrokeThickness="1" Stroke="#aaaaaa">Line>
                        StackPanel>
                        <DataTemplate.Triggers>
                            <DataTrigger Binding="{Binding NumberVisibility}" Value="Hidden">
                                <Setter TargetName="line" Property="Y1" Value="3" />
                            DataTrigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="line" Property="Stroke" Value="RoyalBlue" />
                                <Setter TargetName="text" Property="Foreground" Value="RoyalBlue" />
                            Trigger>
                        DataTemplate.Triggers>
                    DataTemplate>
                ListBox.ItemTemplate>
            ListBox>
        Grid>
    Window>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    MainWindow.xaml.cs

    using System.Collections.Generic;
    using System.Windows;
    namespace WpfApp7
    {
        public class RulerChip
        {
            public double Number { get; set; }
            public Visibility NumberVisibility { get; set; }
    
        }
        /// 
        /// Interaction logic for MainWindow.xaml
        /// 
        public partial class MainWindow : Window
        {
    
            public List<RulerChip> Chips { get; set; }=new List<RulerChip>();
            public MainWindow()
            {
                InitializeComponent();
                DataContext = this;
                for (int i = 0; i < 100; i++)
                {
                    Chips.Add(new RulerChip() { Number=i/10.0, NumberVisibility = (i%10==0)?Visibility.Visible:Visibility.Hidden});
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    三、效果预览

    在这里插入图片描述


    总结

    以上就是今天要讲的内容,本文仅仅简单介绍了ListBox实现尺子控件的方法,很容易实现。而且因为使用了虚拟化容器理论上性能很好,就算是几百万刻度绘制也估计不会卡顿。所以在此基础上可以进行一定的拓展,比如利用dpi实现物理尺子,以及实现时间尺的缩放功能等。总的来说,这是一个易于实现且拓展性也不错的尺子实现方案。

  • 相关阅读:
    AutoAugment介绍及论文解析
    关于mysql本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止问题
    抠图专题1:抠出白色陶瓷杯(每天一个PS小项目)
    罗克韦尔AB PLC Logix5000中如何创建标签并使用标签进行编程?
    [UNR #6]稳健型选手
    连续词袋模型(Continous bag of words, CBOW)
    DVWA教程详细的DVWA-CSRF全等级通关教程
    机器学习---决策树的划分依据(熵、信息增益、信息增益率、基尼值和基尼指数)
    paddleClas分类实践记录
    【linux命令讲解大全】105.掌握磁盘配额管理的edquota命令
  • 原文地址:https://blog.csdn.net/u013113678/article/details/125814664