栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

wpf 自定义控件

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

wpf 自定义控件

示例

取自《WPF 自学手册》

效果:

用户控件

添加一个用户控件, 名称为: NumberPanel

xaml

    
        
            
            
        
        
            
            
        

        
            
        

        
cs
using System;
using System.Windows;
using System.Windows.Controls;

namespace khl.dbtool.control
{
    public partial class NumberPanel : UserControl
    {
        public NumberPanel()
        {
            InitializeComponent();
        }


        /// 
        /// 最小值
        /// 
        private const decimal MinValue = 0;

        /// 
        /// 最大值
        /// 
        private const decimal MaxValue = 100;

        #region 依赖属性

        /// 
        /// 数值
        /// 
        public decimal NumberValue
        {
            get => (decimal)GetValue(NumberValueProperty);
            set => SetValue(NumberValueProperty, value);
        }

        public static readonly DependencyProperty NumberValueProperty = DependencyProperty.Register(
            // 依赖属性名称
            "NumberValue",
            // 依赖属性类型
            typeof(decimal), 
            // 注册依赖属性到哪个类
            typeof(NumberPanel),
            new PropertyMetadata(
                // 默认值
                MinValue, 
                // 属性值改变时的回调
                new PropertyChangedCallback(OnNumberValueChanged), 
                // 修正属性值
                new CoerceValueCallback(CoerceNumberValue)));

        private static void OnNumberValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
        {
            if (d is not NumberPanel control)
            {
                return;
            }

            RoutedPropertyChangedEventArgs e = new RoutedPropertyChangedEventArgs((decimal)args.OldValue, (decimal)args.NewValue, NumberValueChangedEvent);
            control.OnNumberValueChanged(e);
        }

        private static object CoerceNumberValue(DependencyObject d, object value)
        {
            decimal newValue = (decimal)value;
            NumberPanel control = d as NumberPanel;

            newValue = Math.Max(MinValue, Math.Min(MaxValue, newValue));

            return newValue;
        }

        

        #endregion


        #region 路由事件

        public static readonly RoutedEvent NumberValueChangedEvent = EventManager.RegisterRoutedEvent("NumberValueChanged", RoutingStrategy.Bubble,
            typeof(RoutedPropertyChangedEventHandler), typeof(NumberPanel));

        public event RoutedPropertyChangedEventHandler NumberValueChanged
        {
            add { AddHandler(NumberValueChangedEvent, value); }
            remove { RemoveHandler(NumberValueChangedEvent, value); }
        }

        protected virtual void OnNumberValueChanged(RoutedPropertyChangedEventArgs args)
        {
            RaiseEvent(args);
        }

        #endregion


        #region 控件事件

        private void upButton_Click(object sender, RoutedEventArgs e)
        {
            NumberValue++;
        }

        private void downButton_Click(object sender, RoutedEventArgs e)
        {
            NumberValue--;
        }

        #endregion
    }
}
使用用户控件

自定义控件 添加一个自定义控件


此时引用可能会报错:

严重性	代码	说明	项目	文件	行	禁止显示状态
错误	MC3000	“给定编码中的字符无效。 第 16 行,位置 56。.”XML 无效。	khl.dbtool.control	F:codewpfkhl.dbtoolkhl.dbtool.controlThemesGeneric.xaml	16	

解决方法:

关闭所有文件, 只打开自定义控件的xaml, 然后另存为UTF编码, 再重新编译即可

随便写一个东西, 然后引用
xaml




    

引用


看到效果则说明新建自定义控件成功

Generic.xaml include 其他 xaml

如果所有的自定义控件的默认主体都放在Generic.xaml中不便于管理, 此时可以添加一个新的文件, 然后在Generic.xaml中引用即可
Generic.xaml




    
        
    


NumberBoxThemesGeneric.xaml


    

cs

using System.Windows;
using System.Windows.Controls;

namespace khl.dbtool.control
{
    public class NumberBox : Control
    {
        static NumberBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(NumberBox), new FrameworkPropertyMetadata(typeof(NumberBox)));
        }
    }
}

文件夹结构

控件xaml

和之前的用户控件的区别:

  1. 主要控件的x:Name属性以 PART 开头, 表示这个控件在控件后台代码需要使用
  2. 按钮的相应由事件变更为命令

    

控件cs

和之前的控件后台代码相比, 按钮的时间代码变更为命令

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace khl.dbtool.control
{
    public class NumberBox : Control
    {
        /// 
        /// 最小值
        /// 
        private const decimal MinValue = 0;

        /// 
        /// 最大值
        /// 
        private const decimal MaxValue = 100;

        static NumberBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(NumberBox), new FrameworkPropertyMetadata(typeof(NumberBox)));

            InitCommand();
        }

        private static void InitCommand()
        {
            increaseCommand = new RoutedCommand("IncreaseCommand", typeof(NumberBox));
            CommandManager.RegisterClassCommandBinding(typeof(NumberBox), new CommandBinding(increaseCommand, IncreaseCommandHandler));

            decreaseCommand = new RoutedCommand("DecreaseCommand", typeof(NumberBox));
            CommandManager.RegisterClassCommandBinding(typeof(NumberBox), new CommandBinding(decreaseCommand, DecreaseCommandHandler));
        }

        #region 依赖属性

        /// 
        /// 数值
        /// 
        public decimal NumberValue
        {
            get => (decimal)GetValue(NumberValueProperty);
            set => SetValue(NumberValueProperty, value);
        }

        public static readonly DependencyProperty NumberValueProperty = DependencyProperty.Register("NumberValue",typeof(decimal),typeof(NumberBox),
            new PropertyMetadata(MinValue,new PropertyChangedCallback(OnNumberValueChanged),new CoerceValueCallback(CoerceNumberValue)));

        private static void OnNumberValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
        {
            if (d is not NumberBox control)
            {
                return;
            }

            RoutedPropertyChangedEventArgs e = new RoutedPropertyChangedEventArgs((decimal)args.OldValue, (decimal)args.NewValue, NumberValueChangedEvent);
            control.OnNumberValueChanged(e);
        }

        private static object CoerceNumberValue(DependencyObject d, object value)
        {
            decimal newValue = (decimal)value;
            NumberBox control = d as NumberBox;

            newValue = Math.Max(MinValue, Math.Min(MaxValue, newValue));

            return newValue;
        }

        #endregion


        #region 路由事件

        public static readonly RoutedEvent NumberValueChangedEvent = EventManager.RegisterRoutedEvent("NumberValueChanged", RoutingStrategy.Bubble,
            typeof(RoutedPropertyChangedEventHandler), typeof(NumberBox));

        public event RoutedPropertyChangedEventHandler NumberValueChanged
        {
            add { AddHandler(NumberValueChangedEvent, value); }
            remove { RemoveHandler(NumberValueChangedEvent, value); }
        }

        protected virtual void OnNumberValueChanged(RoutedPropertyChangedEventArgs args)
        {
            RaiseEvent(args);
        }

        #endregion


        #region 命令

        /// 
        /// 递增命令
        /// 
        private static RoutedCommand increaseCommand;
        public static RoutedCommand IncreaseCommand
        {
            get { return increaseCommand; }
        }
        private static void IncreaseCommandHandler(object sender, ExecutedRoutedEventArgs e)
        {
            NumberBox control = sender as NumberBox;
            if (null != control)
            {
                control.OnIncreaseCommandHandler();
            }
        }

        private void OnIncreaseCommandHandler()
        {
            NumberValue++;
        }


        /// 
        /// 递减命令
        /// 
        private static RoutedCommand decreaseCommand;
        public static RoutedCommand DecreaseCommand
        {
            get { return increaseCommand; }
        }
        private static void DecreaseCommandHandler(object sender, ExecutedRoutedEventArgs e)
        {
            NumberBox control = sender as NumberBox;
            if (null != control)
            {
                control.OnDecreaseCommandHandler();
            }
        }

        private void OnDecreaseCommandHandler()
        {
            NumberValue++;
        }

        #endregion
    }
}
引用xaml

	



	
		
		
		
		
	

运行效果

编辑控件模板

此时可以编辑控件模板
控件模板内容:


	

运行效果

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1023886.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号