112 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.ComponentModel;
 | 
						|
using System.Diagnostics.CodeAnalysis;
 | 
						|
using System.Linq;
 | 
						|
using System.Runtime.CompilerServices;
 | 
						|
using System.Text;
 | 
						|
using System.Threading.Tasks;
 | 
						|
using System.Windows;
 | 
						|
using System.Windows.Controls;
 | 
						|
using System.Windows.Data;
 | 
						|
using System.Windows.Documents;
 | 
						|
using System.Windows.Input;
 | 
						|
using System.Windows.Media;
 | 
						|
using System.Windows.Media.Imaging;
 | 
						|
using System.Windows.Navigation;
 | 
						|
using System.Windows.Shapes;
 | 
						|
 | 
						|
namespace Deedy.Design
 | 
						|
{
 | 
						|
    /// <summary>
 | 
						|
    /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
 | 
						|
    ///
 | 
						|
    /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
 | 
						|
    /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
 | 
						|
    /// 元素中:
 | 
						|
    ///
 | 
						|
    ///     xmlns:MyNamespace="clr-namespace:Deedy.Design"
 | 
						|
    ///
 | 
						|
    ///
 | 
						|
    /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
 | 
						|
    /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
 | 
						|
    /// 元素中:
 | 
						|
    ///
 | 
						|
    ///     xmlns:MyNamespace="clr-namespace:Deedy.Design;assembly=Deedy.Design"
 | 
						|
    ///
 | 
						|
    /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
 | 
						|
    /// 并重新生成以避免编译错误:
 | 
						|
    ///
 | 
						|
    ///     在解决方案资源管理器中右击目标项目,然后依次单击
 | 
						|
    ///     “添加引用”->“项目”->[浏览查找并选择此项目]
 | 
						|
    ///
 | 
						|
    ///
 | 
						|
    /// 步骤 2)
 | 
						|
    /// 继续操作并在 XAML 文件中使用控件。
 | 
						|
    ///
 | 
						|
    ///     <MyNamespace:DeedyViewer/>
 | 
						|
    ///
 | 
						|
    /// </summary>
 | 
						|
    public class DeedyViewer : Control, IDeedyViewer
 | 
						|
    {
 | 
						|
        static DeedyViewer()
 | 
						|
        {
 | 
						|
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DeedyViewer), new FrameworkPropertyMetadata(typeof(DeedyViewer)));
 | 
						|
        }
 | 
						|
 | 
						|
        public event PropertyChangedEventHandler? PropertyChanged;
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// 发送属性变更通知
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="propertyName">发生变更的属性</param>
 | 
						|
        protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 | 
						|
        /// <summary>
 | 
						|
        /// 读取一个字段的值
 | 
						|
        /// </summary>
 | 
						|
        /// <typeparam name="T">值的类型,可以通过参数进行自动判定</typeparam>
 | 
						|
        /// <param name="field">字段的引用【注意:此参数通过引用传递】</param>
 | 
						|
        /// <param name="propertyName">属性名称;如果在属性的读取访问器中调用可以自动注入</param>
 | 
						|
        /// <returns>字段中的值</returns>
 | 
						|
        protected virtual T GetField<T>(ref T field, [CallerMemberName] string? propertyName = null)
 | 
						|
        {
 | 
						|
            return field;
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// 检查新值是否与原值相等,如果不相等便赋值并发出通知
 | 
						|
        /// </summary>
 | 
						|
        /// <typeparam name="T">值的类型,可以通过参数进行自动判定</typeparam>
 | 
						|
        /// <param name="field">字段的引用【注意:此参数通过引用传递】</param>
 | 
						|
        /// <param name="value">字段的新值</param>
 | 
						|
        /// <param name="propertyName">要进行变更通知的属性名称;如果在属性的设置访问器中调用可以自动注入</param>
 | 
						|
        /// <returns>值是否有变更</returns>
 | 
						|
        protected virtual bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
 | 
						|
        {
 | 
						|
            if (EqualityComparer<T>.Default.Equals(field, value)) return false;
 | 
						|
            field = value;
 | 
						|
            OnPropertyChanged(propertyName);
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
 | 
						|
        [AllowNull, DefaultValue(null)]
 | 
						|
        /// <summary>
 | 
						|
        /// 动作节点
 | 
						|
        /// </summary>
 | 
						|
        public IDeedyAction DeedyAction
 | 
						|
        {
 | 
						|
            get { return (IDeedyAction)GetValue(DeedyActionProperty); }
 | 
						|
            set { SetValue(DeedyActionProperty, value); }
 | 
						|
        }
 | 
						|
        public static readonly DependencyProperty DeedyActionProperty =
 | 
						|
            DependencyProperty.Register("DeedyAction", typeof(IDeedyAction), typeof(DeedyViewer), new PropertyMetadata(null,
 | 
						|
                (d, e) => (d as DeedyViewer)?.DeedyAction_PropertyChangedCallback(d, e)));
 | 
						|
        /// <summary>
 | 
						|
        /// 处理「DeedyActionViewer.DeedyAction」属性变更
 | 
						|
        /// </summary>
 | 
						|
        protected virtual void DeedyAction_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
 | 
						|
        {
 | 
						|
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |