• C# 控件重叠

    2007-08-08 16:17:00
    做项目过程中遇到要将两个控件重叠,然后动态控制两个控件的显示,尝试了半天发现了一些规律,解决了眼下问题,不过正确与否还有待进一步验证。1、当两个控件重叠时,先使用 this.controls.Add() 的控件放在最上面;...
    做项目过程中遇到要将两个控件重叠,然后动态控制两个控件的显示,尝试了半天发现了一些规律,解决了眼下问题,不过正确与否还有待进一步验证。
    1、当两个控件重叠时,先使用 this.controls.Add() 的控件放在最上面;
    2、可以使用 BringToFront() 方法将控件直接置于最上方,使用 SendToBack() 方法将控件置于最下方;
    3、多个控件重叠,更改顺序就可以综合使用 Remove 和 Add 方法来重新添加控件,先添加的控件显示在最上方。 
    展开全文
  • 最近用C#小程序,里面用到了PictureBox和Label控件,因为某些原因必须将两者重叠使用(PictureBox在下层,Label在上层),结果却发现即使是设置Label的BackColor为Transparent,在实际运行时Label的背景依然...

           最近用C#写个小程序,里面用到了PictureBox和Label两种控件,因为某些原因必须将两者重叠使用(PictureBox在下层,Label在上层),结果却发现即使是设置Label的BackColor为Transparent,在实际运行时Label的背景依然是白色非透明。查阅相关文档后发现解决方法主要有两种,一种是通过自定义控件,重写控件的OnPaint()等方法来实现的,可以达到部分透明的效果,但是当界面反复刷新时显示效果不好,可能会出现黑影或闪烁,因此我并未采用。另一种解决方案是在控件初始化时将PictureBox置于底层,将Label控件置于顶层,然后设置Label控件的BackColor为Transparent,指定其Parent属性为PictureBox的对应实例。

    PictureBox pb = new PictureBox();
    Label lb = new Label();
    pb.SendToBack();
    lb.Parent = pb;
    lb.BackColor = Color.Transparent;
    lb.BringToFront();
    this.Controls.Add(pb);
    pb.Controls.Add(lb);

     

    展开全文
  • 自定义控件的性能优化主要包括三方面:性能优化、绘制优化、布局优化。 性能优化: 使用工具进行排查,包括:Memory Monitor、Allocation Tracker、MAT、LeakCanary. 避免在onDraw()和onLayout()中创建对象,因为这...

    自定义控件的性能优化主要包括三方面:性能优化、绘制优化、布局优化。

    性能优化:
    1. 使用工具进行排查,包括:Memory Monitor、Allocation Tracker、MAT、LeakCanary.
    2. 避免在onDraw()和onLayout()中创建对象,因为这两个方法在绘制过程中会被频繁的调用。
    3. 使用较小的数据结构,如SparseArray。
    4. 对Bitmap进行压缩和复用。
    5. 避免内存泄漏。
    绘制优化
    1. 保证每帧耗时操作不能超过16ms。由于Android中每秒传输帧数(FPS)不能低于60fps,所以,需要保证每帧耗时操作不能超过16ms。方法:在onDraw()绘制前开始计时,在结束后计算绘制时间,从而计算onDraw()绘制的时间。
    2. 通过主线程Looper处理消息或事件的时间差来监控应用整体卡顿的情况,例如第三方工具:BlockCanary。
    3. 避免绘制过度。例如,控件之间的重叠,空间本身与背景之间的重叠等。在手机的开发者选项中开启调试GPU过度绘制,选择显示过度绘制区域,查看手机屏幕上是否有颜色过深的区域,则为过度绘制的区域。
    4. 减少无意义的绘制,例如进度条更新显示,如果读取文件的数据量不超过总文件的1%,就无需更新绘制。
    布局优化
    1. 减少布局的重叠和嵌套。如果自定义控件继承RelativeLayout,该布局的父布局也是RelativeLayout,则可以将子布局的根节点设置< merge>< /merge> 或者< viewStub> < /viewStub> viewStub介绍
    2. 尽量使用相对布局LinearLayout和约束布局ContraintLayout。
    展开全文
  • WPF自定义按钮-DoubleAnimation动画效果展示原理下面为其中一个样式的代码到此代码都结束了补充...自定义控件继承Button,模板为两个重叠的Border 下面为其中一个样式的代码 自定义控件文件(MyButton.cs),自...

    效果展示

    在这里插入图片描述
    最近在看Wpf的书,初了解Wpf,也没做过C#和Wpf的项目。
    如果下述有不妥的地方请多多包含,有错误,还请指教。

    原理

    自定义控件继承Button,模板为两个重叠的Border

    下面为其中一个样式的代码

    1. 自定义控件文件(MyButton.cs),自定生成的代码先暂时什么都不用改
    using System.Windows;
    using System.Windows.Controls;
    
    namespace CSDN01
    {
        public class MyButton : Button
        {
            static MyButton()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(MyButton), new FrameworkPropertyMetadata(typeof(MyButton)));
            }
        }
    }
    
    1. 项目2,资源字典文件(TemplateMyButton.xaml),我暂时先把属性设成固定值,后期再改成依赖属性
      属性UseLayoutRounding=“False”
      的设置是一个注意点(后续♦1处说明)
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:local="clr-namespace:CSDN01">
        <ControlTemplate x:Key="TemplateMyButton" TargetType="{x:Type local:MyButton}">
            <Grid UseLayoutRounding="False">
                <Border x:Name="bd1" Background="LightCyan">
                    <TextBlock Text="按钮" FontSize="12" Foreground="DarkCyan"
                                   HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
                <Border x:Name="bd2" Background="DarkCyan" Height="0">
                    <TextBlock Text="按钮" FontSize="12" Foreground="LightCyan"
                                   HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </Grid>
        </ControlTemplate>
    </ResourceDictionary>
    
    1. App.xaml里添加资源字典文件
    <Application x:Class="CSDN01.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:CSDN01"
                 StartupUri="MainWindow.xaml">
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="TemplateMyButton.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    </Application>
    
    1. 主窗口文件(MainWindow.xaml)
      属性UseLayoutRounding=“True”
      的设置是一个注意点(后续♦2处说明)
    <Window x:Class="CSDN01.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:CSDN01"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid UseLayoutRounding="True">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="3*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <local:MyButton Template="{StaticResource TemplateMyButton}" Grid.Column="1"/>
            <local:MyButton Template="{StaticResource TemplateMyButton}" Grid.Column="2"/>
            <local:MyButton Template="{StaticResource TemplateMyButton}" Grid.Column="3"/>
            <local:MyButton Template="{StaticResource TemplateMyButton}" Grid.Column="4"/>
        </Grid>
    </Window>
    
    1. 上述步骤后,大体窗口的样子成型
      在这里插入图片描述

    2. 现在重写MyButton.cs文件添加DoubleAnimation动画
      属性FillBehavior
      的设置是一个注意点(后续♦3处说明)

    using System;
    using System.Windows.Media.Animation;
    
           /// <summary>
            /// 动画对象
            /// </summary>
            private DoubleAnimation myAnimation = new DoubleAnimation();
    
            /// <summary>
            /// 重写MouseEnter事件
            /// </summary>
            /// <param name="e"></param>
            protected override void OnMouseEnter(MouseEventArgs e)
            {
                base.OnMouseEnter(e);
    
                // 获取MyButton内部子控件
                Border bd1 = GetTemplateChild("bd1") as Border;
                Border bd2 = GetTemplateChild("bd2") as Border;
    
                // 设置属性
                myAnimation.From = 0;                             // 动画初始值
                myAnimation.To = bd1.ActualHeight;                // 动画终了值
                myAnimation.Duration = TimeSpan.FromSeconds(0.5); // 0.5秒内执行动画
                myAnimation.FillBehavior = FillBehavior.HoldEnd;  // 动画结束后,属性值保持终了状态
    
                // 在高度属性上执行动画
                bd2.BeginAnimation(HeightProperty, myAnimation);
            }
    
            /// <summary>
            /// 重写MouseLeave事件
            /// </summary>
            /// <param name="e"></param>
            protected override void OnMouseLeave(MouseEventArgs e)
            {
                base.OnMouseLeave(e);
    
                // 获取MyButton内部子控件
                Border bd1 = GetTemplateChild("bd1") as Border;
                Border bd2 = GetTemplateChild("bd2") as Border;
    
                // 添加并执行动画
                myAnimation.From = bd1.ActualHeight;              // 动画初始值
                myAnimation.To = 0;                               // 动画终了值
                myAnimation.Duration = TimeSpan.FromSeconds(0.5); // 0.5秒内执行动画
                myAnimation.FillBehavior = FillBehavior.Stop;     // 动画结束后,属性值还原为动画出师值
    
                // 在高度属性上执行动画
                bd2.BeginAnimation(HeightProperty, myAnimation);
            }
    
    1. 上述步骤后,整个按钮算是大体全部结束了,后续要添加依赖属性,这样可以设置自己想要的背景色,文字大小颜色等属性。
      在这里插入图片描述

    2. 依赖属性的设置(这里就只设置2个依赖属性做例子)
      依赖属性的代码有快捷键:输入propdp,然后按2次Tab键
      往MyButton.cs添加下面的代码
      PropertyMetadata里设置的是初期值

    using System.Windows.Media;
    
            /// <summary>
            /// 上层背景色(变动层)
            /// </summary>
            public SolidColorBrush UpBackground
            {
                get { return (SolidColorBrush)GetValue(UpBackgroundProperty); }
                set { SetValue(UpBackgroundProperty, value); }
            }
            public static readonly DependencyProperty UpBackgroundProperty =
                DependencyProperty.Register("UpBackground", typeof(SolidColorBrush), typeof(MyButton), new PropertyMetadata(new SolidColorBrush(Colors.DarkCyan)));
    
            /// <summary>
            /// 动画执行时间属性(秒)
            /// </summary>
            public double AnimationSeconds
            {
                get { return (double)GetValue(AnimationSecondsProperty); }
                set { SetValue(AnimationSecondsProperty, value); }
            }
            public static readonly DependencyProperty AnimationSecondsProperty =
                DependencyProperty.Register("AnimationSeconds", typeof(double), typeof(MyButton), new PropertyMetadata(0.2));
    

    对MyButton.cs文件再次进行修改

                // 修改前
                myAnimation.Duration = TimeSpan.FromSeconds(0.5); // 0.5秒内执行动画
                // 修改后
                myAnimation.Duration = TimeSpan.FromSeconds(AnimationSeconds); // 制定时间内执行动画(默认0.2秒)
    

    对TemplateMyButton.xaml文件再次进行修改

                <!--变更前-->
                <Border x:Name="bd2" Background="DarkCyan" Height="0">
                <!--变更后-->
                <Border x:Name="bd2" Background="{TemplateBinding UpBackground}" Height="0">
    

    也可以用Button固有的属性来设置MyButton的样式

                <!--变更前-->
                <TextBlock Text="按钮" FontSize="12" 
                <!--变更后-->
                <TextBlock Text="{TemplateBinding Content}"
    

    当然要在MainWindow.xaml文件里设置Content的值

            <local:MyButton Template="{StaticResource TemplateMyButton}" Grid.Column="1" Content="首页"/>
            <local:MyButton Template="{StaticResource TemplateMyButton}" Grid.Column="2" Content="产品"/>
            <local:MyButton Template="{StaticResource TemplateMyButton}" Grid.Column="3" Content="技术"/>
            <local:MyButton Template="{StaticResource TemplateMyButton}" Grid.Column="4" Content="联系我们"/>
    

    到此代码都结束了

    在这里插入图片描述

    补充上述3点我在做样式的注意点

    1. 先说注意点♦2:UseLayoutRounding=“True”
      做个小例子
            <Grid Grid.Row="2" Grid.Column="1">
                <Border Background="Black"/>
                <Border Background="White"/>
            </Grid>
    

    上述在一个单元格里放至2个Border,白色覆盖在黑色上面,下面是没有UseLayoutRounding=“True”
    的运行结果
    在这里插入图片描述

    有2根比较明显的底色黑线漏出来了,我这次给的MyButton例子是不会出现这个的,因为一个是隐藏的,一个是显示的。但是如果自己想做别的动画,需要多个重叠控件的话,就可能会出现这个现象。
    至于为什么,我也说不出,给2张书上的说明:
    在这里插入图片描述

    在这里插入图片描述

    引用的是【WPF编程宝典–使用C#2012和.NET 4.5 第4版】的64,65页。

    1. 再说注意点♦1:UseLayoutRounding=“False”
      举个小例子,去掉♦1处的:UseLayoutRounding=“False”
       <Grid UseLayoutRounding="True">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <local:MyButton Template="{StaticResource TemplateMyButton}" Grid.Column="1" Content="首页" Padding="5"/>
    

    为了防止黑线,我在最外面添加了UseLayoutRounding=“True”,如果MyButton被强制设置了宽度,又加上了Padding,MyButton的实际宽度编程110,我用慢动作看一下运行的实际动画:
    在这里插入图片描述

    文字在上下抖动,原因大概就是高度是小数,不停变化高度的时候,由于布局舍入导致居中的位置上下1像素浮动。这时候就要把布局舍入给关了。

    1. 再说注意点♦3:属性FillBehavior
      用一个别的按钮样式说明,没有FillBehavior属性,被拉伸后的效果
      拉伸前:
      在这里插入图片描述
      拉伸后:
      在这里插入图片描述

    应该很好理解,原本高宽是考Grid自动生成的,所以控件实际的Hight和Width的值是NaN,所以动画我用的都是ActualHeight和ActualWidth,动画执行的时候,改变的是Hight和Width,把实际的高宽给固定了,所以拉伸后还保持原来的Hight和Width而没有跟随Grid的变化而变化,所以要在鼠标离开后,把NaN的值还给他。

    展开全文
  • 结束值的范围,后来发现这样用户操作性太不好,前台代码又很臃肿,干脆想办法写了个自定义控件。首先来看下最终效果吧:  具体的交互基本就是左边框是起始值,右边框是终止值,它们数据的是和两个滑块绑定的...

      今天写搜索界面,有许多值范围搜索的项,先是做了两个Textbox加两个Slider来实现选择起始->结束值的范围,后来发现这样用户操作性太不好,前台代码又很臃肿,干脆想办法写了个自定义的控件。首先来看下最终效果吧:

       


      具体的交互基本就是左边框是起始值,右边框是终止值,它们数据的是和两个滑块绑定的,会互相更新。左边的滑块是不能拖到右边滑块之外的,同理右边也不能到左边,如果输入的值超出(小于)上限值(下限),则会把值取为上限值(下限)。

      我的思路就是定义两个Slider,然后拼起来,哈哈!好吧,来看前台代码:

     1 <UserControl x:Class="FS.PresentationManagement.Controls.SilderArrange"
     2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4              Name="UC_Arrange" Loaded="UC_Arrange_Loaded">
     5     <StackPanel Orientation="Horizontal" Height="{Binding ElementName=UC_Arrange,Path=SilderHeight}" >
     6         <TextBox Text="{Binding ElementName=SL_Bat1,Path=Value}" KeyUp="TextBox_KeyUp1" Width="35" Margin="0,3" BorderBrush="CornflowerBlue" />
     7         <Canvas Width="{Binding ElementName=UC_Arrange,Path=SilderWidth}" Margin="0,0,5,0">
     8             <Slider Name="SL_Bat1"
     9                 Value="{Binding ElementName=UC_Arrange,Path=StartValue}"
    10                 Minimum="{Binding ElementName=UC_Arrange,Path=Minimum}"
    11                 Maximum="{Binding ElementName=UC_Arrange,Path=Maximum}"
    12                 SelectionStart="{Binding ElementName=UC_Arrange,Path=StartValue}"
    13                 SelectionEnd="{Binding ElementName=UC_Arrange,Path=EndValue}"
    14                 Width="{Binding ElementName=UC_Arrange,Path=SilderWidth}"
    15                 TickFrequency="{Binding ElementName=UC_Arrange,Path=SliderTickFrequency}"
    16                 FocusVisualStyle="{x:Null}"
    17                 CacheMode="BitmapCache"
    18                 IsSelectionRangeEnabled="True"
    19                 TickPlacement="BottomRight"
    20                 IsSnapToTickEnabled="True"
    21                 VerticalAlignment="Center"
    22                 Margin="2"
    23                 ValueChanged="SL_Bat1_ValueChanged">
    24                 <Slider.Clip>
    25                     <RectangleGeometry Rect="{Binding ElementName=UC_Arrange,Path=StartRect}" />
    26                 </Slider.Clip>
    27             </Slider>
    28             <Slider Name="SL_Bat2" 
    29                 Value="{Binding ElementName=UC_Arrange,Path=EndValue}" 
    30                 Minimum="{Binding ElementName=UC_Arrange,Path=Minimum}" 
    31                 Maximum="{Binding ElementName=UC_Arrange,Path=Maximum}" 
    32                 SelectionStart="{Binding ElementName=UC_Arrange,Path=StartValue}" 
    33                 SelectionEnd="{Binding ElementName=UC_Arrange,Path=EndValue}" 
    34                 Width="{Binding ElementName=UC_Arrange,Path=SilderWidth}"
    35                 TickFrequency="{Binding ElementName=UC_Arrange,Path=SliderTickFrequency}"
    36                 FocusVisualStyle="{x:Null}"
    37                 CacheMode="BitmapCache"
    38                 IsSelectionRangeEnabled="True"                
    39                 TickPlacement="BottomRight"
    40                 IsSnapToTickEnabled="True"
    41                 VerticalAlignment="Center"
    42                 Margin="2"
    43                 ValueChanged="SL_Bat2_ValueChanged">
    44                 <Slider.Clip>
    45                     <RectangleGeometry Rect="{Binding ElementName=UC_Arrange,Path=EndRect}" />
    46                 </Slider.Clip>                
    47             </Slider>
    48         </Canvas>
    49         <TextBox Text="{Binding ElementName=SL_Bat2,Path=Value}" KeyUp="TextBox_KeyUp2" Width="35" Margin="0,3" BorderBrush="CornflowerBlue"/>        
    50     </StackPanel>
    51 </UserControl>

      没错,我这里用的是Canvas,让两个Slider重叠,然后通过Clip剪裁,然后各个控件的值基本都是绑定到了后台的依赖属性,剪裁的矩形范围也不例外,后台会根据滑块的位置实时更新前台界面,让它们看起来很“和谐”。考虑到剪裁可能产生的效率问题,我把两个Slider的CacheMode都设置成了“BitmapCache”,也就是说会用GPU来计算界面元素。FocusVisualStyle="{x:Null}"这个设置则是让XP的机器显示Slider的时候不会出现很丑的虚线框。
      至于其它设置,都是常规的设置了,这些绑定到后台的除了剪裁的依赖属性设置的是private外,其它都是public,也就是说,使用的时候可以自己再给这些属性赋值。

      来看下后台代码吧:

    大段的后台代码
      1 using System;
      2 using System.Windows;
      3 using System.Windows.Controls;
      4 using System.Windows.Input;
      5 
      6 namespace FS.PresentationManagement.Controls
      7 {
      8     /// <summary>
      9     /// 双滑块Slider 
     10     /// By lekko
     11     /// </summary>
     12     public partial class SilderArrange : UserControl
     13     {
     14         #region 私有变量
     15 
     16         private static int _width = 150;  // 拖动条初始宽度
     17         private static int _height = 30;  // 高度
     18         private static int _min = 0;      // 最小值
     19         private static int _max = 100;    // 最大值
     20         private static int _freq = 10;    // 出现刻度的间距
     21 
     22         #endregion
     23 
     24         // 构造函数
     25         public SilderArrange()
     26         {
     27             InitializeComponent();            
     28         }        
     29 
     30         #region 私有属性
     31 
     32         /// <summary>
     33         /// 裁剪矩阵(头)
     34         /// </summary>
     35         private Rect StartRect
     36         {
     37             get { return (Rect)GetValue(StartRectProperty); }
     38             set { SetValue(StartRectProperty, value); }
     39         }
     40         private static readonly DependencyProperty StartRectProperty =
     41             DependencyProperty.Register("StartRect", typeof(Rect), typeof(SilderArrange));
     42 
     43         /// <summary>
     44         /// 裁剪矩阵(尾)
     45         /// </summary>
     46         private Rect EndRect
     47         {
     48             get { return (Rect)GetValue(EndRectProperty); }
     49             set { SetValue(EndRectProperty, value); }
     50         }
     51         private static readonly DependencyProperty EndRectProperty =
     52             DependencyProperty.Register("EndRect", typeof(Rect), typeof(SilderArrange));
     53 
     54         #endregion
     55 
     56         #region 公开依赖属性
     57 
     58         /// <summary>
     59         /// 刻度间距,默认为10
     60         /// </summary>
     61         public int SliderTickFrequency
     62         {
     63             get { return (int)GetValue(SliderTickFrequencyProperty); }
     64             set { SetValue(SliderTickFrequencyProperty, value); }
     65         }
     66         public static readonly DependencyProperty SliderTickFrequencyProperty =
     67             DependencyProperty.Register("SliderTickFrequency", typeof(int), typeof(SilderArrange), new PropertyMetadata(_freq));
     68 
     69         /// <summary>
     70         /// 控件高度,默认为30
     71         /// </summary>
     72         public int SilderHeight
     73         {
     74             get { return (int)GetValue(SilderHeightProperty); }
     75             set { SetValue(SilderHeightProperty, value); }
     76         }
     77         public static readonly DependencyProperty SilderHeightProperty =
     78             DependencyProperty.Register("SilderHeight", typeof(int), typeof(SilderArrange), new PropertyMetadata(_height));
     79 
     80         /// <summary>
     81         /// 拖动条宽度,默认为150
     82         /// </summary>
     83         public int SilderWidth
     84         {
     85             get { return (int)GetValue(SilderWidthProperty); }
     86             set { SetValue(SilderWidthProperty, value); }
     87         }
     88         public static readonly DependencyProperty SilderWidthProperty =
     89             DependencyProperty.Register("SilderWidth", typeof(int), typeof(SilderArrange), new PropertyMetadata(_width));
     90 
     91         /// <summary>
     92         /// 最小值,默认为0
     93         /// </summary>
     94         public int Minimum
     95         {
     96             get { return (int)GetValue(MinimumProperty); }
     97             set { SetValue(MinimumProperty, value); }
     98         }
     99         public static readonly DependencyProperty MinimumProperty =
    100             DependencyProperty.Register("Minimum", typeof(int), typeof(SilderArrange), new PropertyMetadata(_min));
    101 
    102         /// <summary>
    103         /// 最大值,默认为100
    104         /// </summary>
    105         public int Maximum
    106         {
    107             get { return (int)GetValue(MaximumProperty); }
    108             set { SetValue(MaximumProperty, value); }
    109         }
    110         public static readonly DependencyProperty MaximumProperty =
    111             DependencyProperty.Register("Maximum", typeof(int), typeof(SilderArrange), new PropertyMetadata(_max));
    112 
    113         /// <summary>
    114         /// 选中开始值,默认为0
    115         /// </summary>
    116         public int StartValue
    117         {
    118             get { return (int)GetValue(StartValueProperty); }
    119             set { SetValue(StartValueProperty, value); }
    120         }
    121         public static readonly DependencyProperty StartValueProperty =
    122             DependencyProperty.Register("StartValue", typeof(int), typeof(SilderArrange));
    123 
    124         /// <summary>
    125         /// 选中结束值,默认为100
    126         /// </summary>
    127         public int EndValue
    128         {
    129             get { return (int)GetValue(EndValueProperty); }
    130             set { SetValue(EndValueProperty, value); }
    131         }
    132         public static readonly DependencyProperty EndValueProperty =
    133             DependencyProperty.Register("EndValue", typeof(int), typeof(SilderArrange), new PropertyMetadata(_max));
    134 
    135         #endregion
    136 
    137         #region 前台交互
    138 
    139         /// <summary>
    140         /// 对两个拖动条进行裁剪
    141         /// </summary>
    142         private void ClipSilder()
    143         {
    144             int selectedValue = EndValue - StartValue;
    145             int totalValue = Maximum - Minimum;
    146             double sliderClipWidth = SilderWidth * (StartValue - Minimum + selectedValue / 2) / totalValue;
    147             // 对第一个拖动条进行裁剪
    148             StartRect = new Rect(0, 0, sliderClipWidth, SilderHeight);
    149             // 对第二个拖动条进行裁剪
    150             EndRect = new Rect(sliderClipWidth, 0, SilderWidth, SilderHeight);
    151         }        
    152 
    153         /// <summary>
    154         /// 初始化裁剪
    155         /// </summary>
    156         private void UC_Arrange_Loaded(object sender, RoutedEventArgs e)
    157         {
    158             ClipSilder();
    159         }
    160 
    161         private void SL_Bat1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    162         {
    163             if (e.NewValue > EndValue)    // 检查值范围
    164                 StartValue = EndValue;    // 超出,重设为最大值
    165             ClipSilder();
    166         }
    167 
    168         private void SL_Bat2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    169         {
    170             if (e.NewValue < StartValue)
    171                 EndValue = StartValue;
    172             ClipSilder();
    173         }
    174 
    175         private void TextBox_KeyUp1(object sender, System.Windows.Input.KeyEventArgs e)
    176         {
    177             try
    178             {               
    179                 if (e.Key == Key.Enter)    // 按回车时确认输入
    180                     StartValue = Convert.ToInt32(((TextBox)sender).Text);
    181             }
    182             catch
    183             {
    184             }
    185         }
    186 
    187         private void TextBox_KeyUp2(object sender, KeyEventArgs e)
    188         {
    189             try
    190             {
    191                 if (e.Key == Key.Enter)
    192                     EndValue = Convert.ToInt32(((TextBox)sender).Text);
    193             }
    194             catch
    195             {
    196             }
    197         }       
    198 
    199         #endregion        
    200         
    201     }
    202 }

      这样,在需要使用到这个控件的地方,先在前台代码加上程序集:xmlns:us="clr-namespace:FS.PresentationManagement.Controls",其中“FS.PresentationManagement.Controls”是刚才自定义的控件的命名空间,然后:

    <us:SilderArrange x:Name="SLA_V" SilderWidth="250" Minimum="-50" Maximum="200" />

      就可以了,是不是很方便,呵呵,其实还有不少地方可以改进,不过最少能用了。

    转载请注明原址:http://www.cnblogs.com/lekko/archive/2012/07/23/2604257.html

    转载于:https://www.cnblogs.com/lekko/archive/2012/07/23/2604257.html

    展开全文
  • “基于C#的波形显示控件”设计于09年暑假 源代码:博客园下载 | CSDN下载 解压密码:CSharp_WinForm_Waveform 《基于C#的波形显示控件的实现》写于2009年9月 跳到文章目录(采用锚链接,订阅的朋友可能访问...
  • 整理昨日在群英传上深入学习到的自定义view的知识 一,对现有控件进行扩展: 在原生控件的基础上进行拓展,增加新的功能、修改显示的UI等,一般来说,我们可以在onDraw()方法上对原生控件行为进行拓展 以...
  • c# wpf控件被覆盖问题

    2018-06-19 12:47:25
    首先,说一下场景,相信都看过QQ或者是TIM登录界面,输入这个地方是两个控件自定义的combox和textbox,而且很清晰可以看见,每个控件的border都是1px,鼠标放在任意一个上面,border都会变色。那么问题来了,既然...
  • C#中,可以让控件在最前端显示,也可以在最后端显示,他们的显示顺序是可以控制的,这就涉及到2函数方法  BringToFront();//将控件放置所有控件最前端  SendToBack();//将控件放置所有控件最底端 案例...
  • Problem:有控件A和控件B,位置完全重叠,B覆盖在A上方。换句话说,B只是A的修饰(实现中经常有可能会碰到这样的情况,比如B可能是一png图片,你又不想重写A的模板),我们需要在鼠标操作时透过B直接点击到A。 ...
  • 09年暑假正好在学院实验室呆了一段时间,做了完整的上位机软件(具体实现:根据下位机的指令,实现通过串口来操纵下位机进行实验,并将采集的数据进行处理和保存,并以图形的方式显示),整个项目边学C# WinF...
  • 做了完整的上位机软件(具体实现:根据下位机的指令,实现通过串口来操纵下位机进行实验,并将采集的数据进行处理和保存,并以图形的方式显示),整个项目边学C# WinForm边设计,这波形显示控件就是项目中的一...
  • 发现有bug 文章后面 上一效果图 左边那张图貌似忘了展示一功能 ...貌似这是第一次 直接继承Control写控件 以前都是UserControl 对于写控件真没啥经验 途中遇到各种问题 各种蛋疼 所以代码有啥不对的地方 多包涵 -
  • C#--图表控件(Chart)

    2018-12-21 19:22:00
    采用VS自带的Chart图表控件,制作实时动态显示的折线图,和波形图 涉及知识点: Chart 控件,功能强大,可以绘制柱状图,折线图,波形图,饼状图,大大简化...ChartArea,表示图表区域,一Chart可以绘制多ChartA...
  • WPF中在摄像头视频上叠加控件的解决方案 一、视频呈现  前段时间,在一wpf的项目中需要实时显示ip摄像头,对此的解决方案想必大家都应该知道很多。在winform中,我们可以将一个控件(一般用...
  • 我自己开了一博客这天在写自定义控件的开发 有兴趣的朋友欢迎访问:www.clzf.co 上一效果图 左边那张图貌似忘了展示一功能 源码下载 http://download.csdn.net/detail/crystal_lz/4755251  ...
  • 因为标题栏属于窗口管理器控制,也就受限于操作...可以自定义标题栏, 这里提供一简单的例子!  例子比较简, 大致思路是正常创建窗口后, 屏蔽标题栏, 通过布局将 一QLabel和三按钮 构成一“标题栏
  • 这种流式布局 ,今天我就跟大家一起来动手撸一这种自定义控件. 首先说一下自定义控件的流程: 自定义控件一般要么继承View要么继承ViewGroup View的自定义流程: 继承一View--&gt;重写onMeasure方法--&...
1 2 3 4 5 ... 20
收藏数 715
精华内容 286