WPF 实现滑块选择器

一、新建一个WPF项目,创建一个自定义组件

二、继承于控件ListView,cs代码部分

  [TemplatePart(Name = "PART_Slider", Type = typeof(Border))]
  [TemplatePart(Name = "PART_TransSlider", Type = typeof(TranslateTransform))]
  public class SliderSelector : ListView
  { 
      private double sliderWidth;  //滑块宽度
      private bool canSlider = false;
      static SliderSelector()
      {
          DefaultStyleKeyProperty.OverrideMetadata(typeof(SliderSelector), new FrameworkPropertyMetadata(typeof(SliderSelector)));
      }

      protected override void OnSelectionChanged(SelectionChangedEventArgs e)
      {
          if (canSlider)
          { 
              if (GetTemplateChild("PART_TransSlider") is TranslateTransform transSlider)
              {
                  ///选中滑块改变滑块位置 并入动画 
                  var animation = new DoubleAnimation
                  {
                      Duration = TimeSpan.FromSeconds(0.2),
                      To = sliderWidth * SelectedIndex
                  };
                  transSlider.BeginAnimation(TranslateTransform.XProperty, animation);
              }
          }
          base.OnSelectionChanged(e);
      }


      protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
      {
          if (HasItems)
          {
              sliderWidth = ActualWidth / Items.Count;
              if (GetTemplateChild("PART_Slider") is Border slider)
              {
                  //计算滑块宽度
                  slider.Width = sliderWidth - 8;
              }

              if (GetTemplateChild("PART_TransSlider") is TranslateTransform transSlider)
              {
                  transSlider.X = sliderWidth * SelectedIndex;
              }
              canSlider = true;
          }
          base.OnItemsSourceChanged(oldValue, newValue);
      }

      protected override void OnRender(DrawingContext drawingContext)
      {
          if (HasItems)
          {
              sliderWidth = ActualWidth / Items.Count;
              if (GetTemplateChild("PART_Slider") is Border slider)
              {
                  //计算滑块宽度
                  slider.Width = sliderWidth - 8;
              }

              if (GetTemplateChild("PART_TransSlider") is TranslateTransform transSlider)
              {
                  transSlider.X = sliderWidth * SelectedIndex;
              }
              canSlider = true;
          }
          base.OnRender(drawingContext);
      }

  }

三、Xaml代码部分

    <Style TargetType="{x:Type local:SliderSelector}">
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="Height" Value="40" />
        <Setter Property="SelectedIndex" Value="0" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:SliderSelector}">
                    <Grid>
                        <Border Name="Slider_Bd" Padding="4" CornerRadius="3" Background="#e3e3e3" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"  SnapsToDevicePixels="true">
                            <Border x:Name="PART_Slider" Background="White" HorizontalAlignment="Left" CornerRadius="3">
                                <Border.RenderTransform>
                                    <TranslateTransform x:Name="PART_TransSlider" />
                                </Border.RenderTransform>
                            </Border>
                        </Border>
                        <ItemsPresenter  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel" >
            <Setter.Value>
                <ItemsPanelTemplate >
                    <UniformGrid Rows="1" Width="Auto"/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="ListViewItem">
                    <Setter Property="Padding" Value="15 5" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListViewItem">
                                <Border x:Name="Bd"  Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                                    <ContentPresenter  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
    </Style>

四、使用方式与运行效果

源码地址:https://download.csdn.net/download/qq_38060581/88797810 

  • 24
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: WPF是一种强大的UI框架,它提供了许多控件,其中包括时间选择控件。但是,由于在特定的应用程序中,需要自定义时间选择以满足一些个性化需求。在这种情况下,可以使用WPF自定义控件来创建自己的时间选择控件。 首先,在WPF中创建时间选择控件,需要使用Calendar控件和TimePicker控件。Calendar控件用于显示日期,而TimePicker控件用于选择时间。时间选择控件的主体是StackPanel控件。在StackPanel控件中添加了两个控件Calendar和TimePicker,以实现时间选择的基本功能。 然后,需要在时间选择控件中定义一些附加属性,例如:选定日期、选定时间等等,以实现一些高级功能。 最后,为时间选择控件添加样式,并实现一些触发和动画效果,以使其外观和功能与应用程序的主题相匹配。 实现WPF自定义时间选择可能需要一些时间和经验,但对于需要一个不寻常的时间选择的应用程序来说,是值得的。 这样的时间选择是用户友好的,具有很好的设计和功能,并且以C#编写,可以很容易地与WPF应用程序集成。 ### 回答2: WPF自定义时间选择是一种功能强大、灵活性高的工具,它可以根据需求自行设计不同的选择,可以实现小时、分钟、秒数的选择等多种功能。 首先,我们需要使用WPF自带的DatePicker控件和TimePicker控件来实现时间选择。接下来,我们可以自定义控件的样式和模板,使其更符合我们的设计需求。 在自定义控件的样式时,我们需要设置控件的各个属性,比如控件的边框、背景、字体等。同时,我们可以通过设置样式来调整控件的布局和显示效果。 在时间选择实现中,需要涉及到一些比较复杂的计算,比如计算时间的差值、时间的格式转换等。我们可以使用C#中的DateTime类和TimeSpan类来实现这些功能。 最后对于自定义时间选择的控件事件,需要自定义一些控件事件,使其更加符合我们的设计需求。比如增加或减少系统时钟里的时间。 总而言之,实现WPF自定义时间选择需要对WPF控件、样式、模板、计算和控件事件等各个方面有深入的了解。只有掌握了这些知识,才能够设计出优秀的时间选择,满足用户的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值