• 【WP8】自定义控件


    1、测量和安排布局:MeasureOverride, ArrangeOverride

      

        //测量(传入控件的可用大小)
        protected override Size MeasureOverride(Size availableSize)
        {
            //遍历所有子空间
            foreach (UIElement child in InternalChildren)
            {
                //计算控件可用大小,调用子控件的MeasureOverride方法
                child.Measure(availableSize);
                //获得控件大小
                //child.DesiredSize
            }
    
            //返回给ArrangeOverride调用
            return availableSize;
        }
        
        //安排布局
        protected override Size ArrangeOverride(Size finalSize)
        {
            double x = 0;
            foreach (UIElement child in InternalChildren)
            {
                //安排控件实际渲染位置,通过 DesiredSize获得控件需要的大小
                child.Arrange(new Rect(new Point(x, 0), child.DesiredSize));
                x += child.DesiredSize.Width;
            }
            //返回控件实际布局大小(在父控件通过DesiredSize获得)
            return finalSize;
        }

    2、依赖属性

    //注册依赖属性
        public static DependencyProperty TextProperty = DependencyProperty.Register("MyText",
                                           typeof(string),
                                           typeof(MySilverButton),
                                           new PropertyMetadata("默认属性值", OnTextPropertyChanged));
    
        //依赖属性对应的控件属性
        public string MyText
        {
            get { return (string) GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
        
        //依赖属性回掉函数(static)
        private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //这里MySilverButton是控件类名
            var mySilverButton = d as MySilverButton;
            if (mySilverButton!=null)
                mySilverButton.OnTextPropertyChanged(e);
        }
        
        //属性变化回掉(通过静态函数调用,也可以在静态函数里写)
        private void OnTextPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            var bgTextBlock = GetTemplateChild("ButtonCaption") as TextBlock;
            if (bgTextBlock != null) bgTextBlock.Text = e.NewValue as string;
        }

      在xaml中定义Template时,可以通过{TemplateBinding MyText}绑定依赖属性

    3、在模板加载完成后注册事件和一些初始化操作
      public override void OnApplyTemplate()

    4、获取子控件和资源(定义在Generic.xaml)

        //获取根控件
        var root = (FrameworkElement)GetTemplateChild("RootElement");
        //获取控件资源
        var enter = (Storyboard)root.Resources[MouseEnterAnimation];

    5、元数据

      在控件的定义加上TemplatePart特性,该特性不是必须的,只是一种契约,推荐这样设计控件

      意思是告诉要来写ControlTemplate的用户,你的ControlTemplate中需要有一个x:Name为“LayoutRoot” , 类型为 Panel 的元素 , 因为逻辑部分对这些东西进行了引用,它们将对控件的默认行为起着关键作用, 可以理解为这个控件的最基本元素,是实现默认行为的最小集合,主要是给用户看的

        [TemplatePart(Name = "LayoutRoot", Type = typeof (Panel))]
        [TemplateVisualState(GroupName = "HoverStates", Name = "MouseOver")]
        [TemplateVisualState(GroupName = "HoverStates", Name = "Normal")]
        public class MyControl : Control

    6、视图状态

    //一般在ControlTemplate中的Border控件内部定义

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="HoverStates">
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <ColorAnimation
                            Storyboard.TargetName="BackgroundElement"
                            Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
                            To="Yellow" Duration="0:0:.5" />
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Normal">
                    <Storyboard>
                        <ColorAnimation
                            Storyboard.TargetName="BackgroundElement"
                            Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
                            To="Transparent" Duration="0:0:.5" />
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

      //在视图中定义不同视图状态的过度动画逻辑

      在cs中改变视图状态(this表示该控件)
      VisualStateManager.GoToState(this, "MouseOver", useTransitions);

    参考链接
    1、WPF MeasureOverride And ArrangeOverride
      http://www.cnblogs.com/dingli/archive/2011/04/22/2024786.html
    2、用户自定义控件详解
      http://blog.csdn.net/mr_raptor/article/details/7251942

  • 相关阅读:
    也谈一下关于兔子的问题
    关于sql函数返回表
    关于1000瓶水的问题
    WWF的疑问
    天干和地支
    在若干个整数中找到相加之和为某个整数的所有组合的算法
    输出一个数组的全排列
    新的博客, 新的里程
    学习搜索引擎心得(10.2511.25)
    下一个阶段(用C++重写Lucene的计划)
  • 原文地址:https://www.cnblogs.com/bomo/p/3548114.html
Copyright © 2020-2023  润新知