首先,为什么需要自定义控件
一,项目中重复使用的控件,一处构造,处处使用,方便,简洁。
二,项目整体风格,当然用Style也能控制整个项目的风格,但个人认为用自定义控件,更容易做到,只需要改控件风格,就能让整个项目的风格改变。
三,特殊功能,在项目中往往控件库的控件满足不了需求,这时就需要自己动手,做出一些特殊功能的控件。
四,结构清晰,比如说,在项目中我们布局,是上标题,下类容,常规做法,是用控件拼成这样的布局,如果封装成控件,则只需要 给Title赋值,在填充类容。
第一节
从简单的TextBlock说起
比如说现在有这样一个需求,一个XAML有许多的TextBlock来显示字符,而这些字符长短不同,使TextBlock宽度不一致,是整个XAML看起来很杂乱,怎么办?
这个问题,首先我们会想,给TextBlock定义固定的长度啊,试想,如果一个字段5个字符,一个字段40个字符,这怎么定义长度,难道定义满足40字符宽度的吗?
首先,定义40字符宽的,不可能,这样5个字符岂不是很浪费空间。
那我们怎么办呢?
首先我们想啊,40和5我们取中间22.5,四舍五入后就是20,如果显示20,那剩下的20怎么办呢。我们是不是可以显示15个字符,然后后面用...代替,用鼠标移上去,在显示全部的字符。
如果这样做
第一种做法,写一个Convert类
public class TextBlockConvert : IValueConverter { #region IValueConverter 成员 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value.ToString().Length>15?value.ToString().Substring(0,15)+"...":value.ToString();//如果字符长度大于15截取加.... } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } #endregion }
XAML<TextBlock Text="{Binding Info,Converter={StaticResource txtBlockConvert}}" Margin="5"></TextBlock>
第二种做法就是改装一下TextBlock,让他帮我们做Convert这件事。
public partial class StringFromtControl : UserControl { public StringFromtControl() { InitializeComponent(); } public static readonly DependencyProperty NumberProperty = DependencyProperty.Register("Number", typeof(int), typeof(StringFromtControl), new PropertyMetadata(15,new PropertyChangedCallback(NumbertPropertyChanged)));//注册超过多少字符截取属性,默认超过15个字符,截取加... public int Number { get { return (int)(GetValue(NumberProperty)); } set { SetValue(NumberProperty, value); } } public static void NumbertPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { StringFromtControl sf = (StringFromtControl)obj; sf.Number = (int)args.NewValue; sf.txt_Context.Text = sf.txt_Context.Text.Length > sf.Number ? sf.txt_Context.Text.Substring(0, sf.Number) : sf.txt_Context.Text; } public static readonly DependencyProperty LabelTextProperty = DependencyProperty.Register("LabelText", typeof(string), typeof(StringFromtControl), new PropertyMetadata(new PropertyChangedCallback(OnLabelTextPropertyChanged)));//定义字符属性 public string LabelText { get { return Convert.ToString(GetValue(LabelTextProperty)); } set { SetValue(LabelTextProperty, value); } } public static void OnLabelTextPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { StringFromtControl sf = (StringFromtControl)obj; string text = args.NewValue.ToString(); sf.txt_Context.Text = text.Length > sf.Number ? text.Substring(0, sf.Number) + "...." : text;//当字符长度超过Number长度时,截取加.... } /// <summary> /// 鼠标进去控件时,用ToolTip显示字符 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txt_Context_MouseEnter(object sender, MouseEventArgs e) { Point p = e.GetPosition(canva); ToolTip tool = new ToolTip() { Content = (string)GetValue(LabelTextProperty) }; tool.Name = "tool"; tool.SetValue(Canvas.ZIndexProperty, 1); canva.Children.Add(tool); Canvas.SetLeft(tool, p.X); Canvas.SetTop(tool, p.Y); } /// <summary> /// 鼠标离开时,移除ToolTip /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txt_Context_MouseLeave(object sender, MouseEventArgs e) { if (canva.FindName("tool") != null) { canva.Children.Remove((ToolTip)canva.FindName("tool")); } } }
xaml
<Canvas x:Name="canva" Height="30" Width="100" > <TextBlock x:Name="txt_Context" Canvas.Top="6" MouseEnter="txt_Context_MouseEnter" VerticalAlignment="Center" MouseLeave="txt_Context_MouseLeave"></TextBlock> </Canvas>
调用刚封装的TextBlock
<StackPanel> <my:StringFromtControl Number="20" LabelText="I Belive you" Margin="10"></my:StringFromtControl> <my:StringFromtControl Number="20" LabelText="I Belive you,I Belive you" Margin="10" ></my:StringFromtControl> <my:StringFromtControl Number="20" LabelText="I Belive you,I Belive you,I Belive you" Margin="10"></my:StringFromtControl> </StackPanel>
效果
这样子看起来功能好像是实现了,但是第一个本来就没有超过20个字符,它也显示,这不太好...改改/// <summary> /// 鼠标进去控件时,用ToolTip显示字符 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txt_Context_MouseEnter(object sender, MouseEventArgs e) { Point p = e.GetPosition(canva); ToolTip tool = new ToolTip() { Content = (string)GetValue(LabelTextProperty) }; tool.Name = "tool"; tool.SetValue(Canvas.ZIndexProperty, 1); canva.Children.Add(tool); Canvas.SetLeft(tool, p.X); Canvas.SetTop(tool, p.Y); }
这个事件的改改,当字符不超过的失守我们不需要Add(tool)/// <summary> /// 鼠标进去控件时,用ToolTip显示字符 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txt_Context_MouseEnter(object sender, MouseEventArgs e) { if (((string)GetValue(LabelTextProperty)).Length > (int)GetValue(NumberProperty))//当字符超过设定长度时间添加ToolTip { Point p = e.GetPosition(canva); ToolTip tool = new ToolTip() { Content = (string)GetValue(LabelTextProperty) }; tool.Name = "tool"; tool.SetValue(Canvas.ZIndexProperty, 1); canva.Children.Add(tool); Canvas.SetLeft(tool, p.X); Canvas.SetTop(tool, p.Y); } }
这样就好了,当字符不超过时,不会显示ToolTip。这是我的第一篇博客,写的不好,欢迎批评,这也是自学..所以有不足之处,忘谅解...以后每天一篇 除特殊情况..
自定义silverlight控件
最新推荐文章于 2015-08-27 09:52:08 发布