2018-3-8-WPF-UncommonField-类型是什么
| title | author | date | CreateTime | categories |
|---|---|---|---|---|
|
WPF UncommonField 类型是什么
|
lindexi
|
2018-3-8 16:25:2 +0800
|
2018-3-8 16:9:20 +0800
|
WPF .net framework .net源代码 源代码分析
|
本文告诉大家一个黑科技,这个黑科技在.net 框架外无法使用,这就是 UncommonField 。下面将会告诉大家这个类有什么用。
如果大家有反编译 UIElement 那么就会看到下面的代码
internal static readonly UncommonField<EventHandlersStore> EventHandlersStoreField = new UncommonField<EventHandlersStore>();
那么这个UncommonField是什么?这个类是解决DependencyObject 使用很多内存。使用这个类可以作为轻量的DependencyObject 因为他使用很少的内存。
因为使用了DependencyObject 就会创建很多默认的值,无论使用的是TextBox.Text的依赖属性还是Grid.Row附加的,都会有很多不需要使用的值。但是在框架,需要使用很少的内存,所以就使用UncommonField。
如果使用UncommonField就会去掉很多元数据、校验、通知,UncommonField会使用和DependencyObject 相同的机制,让他可以存放在DependencyObject 中和其他存放的属性一样,在没有改变值的时候会使用上一级、默认的值。所以可以减少一些内存。
因为现在很少人会写出和框架一样的那么多使用依赖属性,所以就不需要使用这个功能。
下面就是UncommonField代码,我添加一些注释
//这个类可以减少内存使用,比使用 DependencyObject 少的内存,这个类在框架使用,不在外面使用
[FriendAccessAllowed] // Built into Base, used by Core and Framework
internal class UncommonField<T>
{
/// <summary>
/// Create a new UncommonField.
/// </summary>
public UncommonField() : this(default(T))
{
} /// <summary>
/// Create a new UncommonField.
/// </summary>
/// <param name="defaultValue">The default value of the field.</param>
public UncommonField(T defaultValue)
{
_defaultValue = defaultValue;
_hasBeenSet = false; lock (DependencyProperty.Synchronized)
{
//注册方法和依赖属性相同
_globalIndex = DependencyProperty.GetUniqueGlobalIndex(null, null); DependencyProperty.RegisteredPropertyList.Add();
}
} /// <summary>
/// 从下面代码可以看到,设置值代码和依赖属性相同
/// Write the given value onto a DependencyObject instance.
/// </summary>
/// <param name="instance">The DependencyObject on which to set the value.</param>
/// <param name="value">The value to set.</param>
public void SetValue(DependencyObject instance, T value)
{
//如果传入的值是空,会有异常
if (instance != null)
{
EntryIndex entryIndex = instance.LookupEntry(_globalIndex); //设置的值如果和默认的相同,那么就直接跳过
// Set the value if it's not the default, otherwise remove the value.
if (!object.ReferenceEquals(value, _defaultValue))
{
//下面的代码进行设置值
instance.SetEffectiveValue(entryIndex, null /* dp */, _globalIndex, null /* metadata */, value, BaseValueSourceInternal.Local);
_hasBeenSet = true;
}
else
{
instance.UnsetEffectiveValue(entryIndex, null /* dp */, null /* metadata */);
}
}
else
{
throw new ArgumentNullException("instance");
}
} /// <summary>
/// 如果没有设置值,就从默认获取,或者上一级,方法和依赖属性相同
/// Read the value of this field on a DependencyObject instance.
/// </summary>
/// <param name="instance">The DependencyObject from which to get the value.</param>
/// <returns></returns>
public T GetValue(DependencyObject instance)
{
if (instance != null)
{
if (_hasBeenSet)
{
EntryIndex entryIndex = instance.LookupEntry(_globalIndex); if (entryIndex.Found)
{
object value = instance.EffectiveValues[entryIndex.Index].LocalValue; if (value != DependencyProperty.UnsetValue)
{
return (T)value;
}
}
return _defaultValue;
}
else
{
return _defaultValue;
}
}
else
{
throw new ArgumentNullException("instance");
}
} /// <summary>
/// Clear this field from the given DependencyObject instance.
/// </summary>
/// <param name="instance"></param>
public void ClearValue(DependencyObject instance)
{
if (instance != null)
{
EntryIndex entryIndex = instance.LookupEntry(_globalIndex); instance.UnsetEffectiveValue(entryIndex, null /* dp */, null /* metadata */);
}
else
{
throw new ArgumentNullException("instance");
}
} internal int GlobalIndex
{
get
{
return _globalIndex;
}
} #region Private Fields private T _defaultValue;
private int _globalIndex;
private bool _hasBeenSet; #endregion
}
从上面的代码可以自己定义一个和他一样的类,用来存放比较少的属性,但是使用不多,因为现在的软件很少需要减少那么少的内存。
参见:https://stackoverflow.com/a/18280136/6116637
https://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/UncommonField.cs
2018-3-8-WPF-UncommonField-类型是什么的更多相关文章
- dotnet 从入门到放弃的 500 篇文章合集
本文是记录我从入门到放弃写的博客 博客包括 C#.WPF.UWP.dotnet core .git 和 VisualStudio 和一些算法,所有博客使用 docx 保存 下载:dotnet 从入门到 ...
- 2018-8-10-dotnet-从入门到放弃的-500-篇文章合集
title author date CreateTime categories dotnet 从入门到放弃的 500 篇文章合集 lindexi 2018-08-10 19:16:52 +0800 2 ...
- 在编写wpf界面时候中出现如下错误: 类型引用不明确。至少有两个名称空间(“System.Windows”和“System.Windows”)中已出现名为“VisualStateManager”的类型。请考虑调整程序集 XmlnsDefinition 特性。
wpf中类型引用不明确.至少有两个名称空间(“System.Windows”和“System.Windows”)中已出现名为“VisualState 你是不是用了WPFToolKit?如果是的,那原因 ...
- WPF视频教程系列笔记
视频二:XAML基础 1.顶级元素 <Window></Window>,<Page></Page>,<Application></Ap ...
- 10、WPF程序集
WPF核心程序集 PresentationCore.dll:这个程序集定义了许多构成WPF GUI层基础的类型.例如包含WPF Ink API(pc笔针输入,手写输入)的支持.几个动画基元以及几个图形 ...
- WPF的消息机制
前言 谈起“消息机制”这个词,我们都会想到Windows的消息机制,系统将键盘鼠标的行为包装成一个Windows Message,然后系统主动将这些Windows Message派发给特定的窗口,实际 ...
- C# 在WPF中使用Exceptionless异常日志框架
登录http://exceptionless.com/官网,注册一个账户. 创建项目 选择wpf项目类型 拷贝下箭头指的这个密钥,过后程序里用的到. 下面我们打开vs,新建一个wpf的项目 打开git ...
- 一步一步部署WPF浏览器应用程序
WPF浏览器应用程序与Silverlight,Asp.net相比,同是发布到服务器,在IE中运行.WPF浏览器应用程序部署起来却相对困难. 相信很多朋友在第一次部署WPF浏览器应用程序时,都遇到&qu ...
- WPF的消息机制(一)- 让应用程序动起来
原文:WPF的消息机制(一)- 让应用程序动起来 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/powertoolsteam/article/det ...
- 手势识别(一)--手势基本概念和ChaLearn Gesture Challenge
以下转自: http://blog.csdn.net/qq1175421841/article/details/50312565 像点击(clicks)是GUI平台的核心,轻点(taps)是触摸平台的 ...
随机推荐
- 记录--浏览器渲染15M文本导致崩溃怎么办
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 最近,我刚刚完成了一个阅读器的txt文件阅读功能,但在处理大文件时,遇到了文本内容过多导致浏览器崩溃的问题. 一般情况下,没有任何样式渲染 ...
- LOTO仪器---如何用LOTO的EMI模块锁定你PCB上的干扰做分析?
在开发电子产品的过程中,电磁干扰(EMI)可能会导致许多问题,可能会在模拟电路上出现很大的噪声,可能导致通讯乱码,可能导致芯片无规律重启,可能会导致数字电路有莫名其妙的误动作. 硬件工程师通常会把主要 ...
- 使用Go语言开发一个短链接服务:一、基本原理
章节 使用Go语言开发一个短链接服务:一.基本原理 使用Go语言开发一个短链接服务:二.架构设计 使用Go语言开发一个短链接服务:三.项目目录结构设计 使用Go语言开发一个短链接服务:四.生成 ...
- Numpy 模块常用函数速查表
序 号 方 法 说 明 1 array(object[, dtype, copy, order, subok, ndmin]) 创建一个数组 2 asarray(a[, dtype, o ...
- 痞子衡嵌入式:给i.MXRT1xxx系列GPIO提早供电会影响DCDC_PSWITCH上电时序导致内部DCDC启动失败
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是给i.MXRT1xxx系列GPIO提早供电会影响DCDC_PSWITCH上电时序导致内部DCDC启动失败. 最近有一个 RW612 产品 ...
- RepPoints:微软巧用变形卷积生成点集进行目标检测,创意满满 | ICCV 2019
RepPoints的设计思想十分巧妙,使用富含语义信息的点集来表示目标,并且巧用可变形卷积来进行实现,整体网络设计十分完备,值得学习 来源:晓飞的算法工程笔记 公众号 论文: RepPoints: ...
- 使用FlashFXP,密钥方式连接Amazon的CE2实例
操作步骤如下: 1.选择"站点" -> "密钥管理器" 2.选择"导入" 3.名称随意填, 类型选择"用于SFTP的RSA/ ...
- Scala mutable.Map可变的Map
1 package chapter07 2 3 import scala.collection.mutable 4 5 object Test09_MutableMap { 6 def main(ar ...
- XML 简介及用法详解
XML 是一种用于存储和传输数据的与软件和硬件无关的工具. 什么是XML? XML代表eXtensible Markup Language(可扩展标记语言).XML是一种与HTML非常相似的标记语言. ...
- C++ 编程必备:对象生命周期管理的最佳实践
在C++中,对象的生命周期是指对象存在的时间段,从对象创建到对象销毁的整个过程.正确地管理对象的生命周期是编写高效.可靠C++代码的关键之一 对象的创建 在C++中,对象可以通过三种方式创建:静态分配 ...