wpf控件设计时支持(3)
- wpf设计时调试
- 编辑模型
- 装饰器
1.wpf设计时调试
为了更好的了解wpf设计时框架,那么调试则非常重要,通过以下配置可以调试控件的设计时代码
(1)将启动项目配置成外部的visual studio ide启动程序devenv.exe
(2)F5启动调试然后会打开一个新的visual studio ide,这个时候要记得重新打开你要调试的那个项目.
以上两个步骤就可以实现设计时调试了
2.编辑模型体系
当选中某些控件出现的设计时,这个选中的控件便成了可编辑的对象. 设计环境会传回一个ModelItem的类,这个类可以帮助你更改控件视图,用于交互.这里的做法与直接更改wpf控件有些不同,如直接改变wpf一个控件的一个属性
this.Content = "Hello";
在设计环境下,也可以获取到处在编辑状态的控件,若采取上面的做法,虽可以变更控件的视图,但却未变更控件在xaml的更改.
设计环境下所有控件的更改都封装在ModelItem类中.做法如下
//selectedContent's Type is ModelItem
selectedContent.Properties["Content"].SetValue("Hello");
//selectedContent.Properties[ContentControl.ContentProperty].SetValue("Hello");
selectedContent类型是ModelItem,其中用Properties索引值获取属性,有两种方式获取属性,字符串和静态项属性
在上篇介绍过控件上下文菜单的设计时做法,我们以此为基础做个示例,以ContentControl为例,如下图
共有4个操作,SetHello和SetRedForeground用于测试ModelItem变更控件视图的功能,
第三个和第四个菜单用于测试变更时事务的操作.(即要么全过,要么全不过)
以下为详细代码
public class ContentMenuProvider : PrimarySelectionContextMenuProvider
{
//略去构造函数添加MenuAcion的代码
void ModelEditingScopeFailMenuAction_Execute(object sender, MenuActionEventArgs e)
{
ModelItem selectedContent = e.Selection.PrimarySelection;
using (ModelEditingScope scope = selectedContent.BeginEdit("test"))
{
//selectedContent's Type is ModelItem
selectedContent.Properties["Content"].SetValue("TextModelEditingScope");
//wrong
selectedContent.Properties["Foreground"].SetValue("Red");
scope.Complete();
}
} void ModelEditingScopeMenuAction_Execute(object sender, MenuActionEventArgs e)
{
ModelItem selectedContent = e.Selection.PrimarySelection;
using (ModelEditingScope scope = selectedContent.BeginEdit("test"))
{
selectedContent.Properties["Content"].SetValue("TextModelEditingScope");
selectedContent.Properties["Foreground"].SetValue(Brushes.Green);
scope.Complete();
}
} void SetRedForegroundMenuAction_Execute(object sender, MenuActionEventArgs e)
{
ModelItem selectedContent = e.Selection.PrimarySelection;
selectedContent.Properties["Foreground"].SetValue(Brushes.Red);
selectedContent.Properties[Control.ForegroundProperty].SetValue(Brushes.Red);
} void SetHelloMenuAction_Execute(object sender, MenuActionEventArgs e)
{
ModelItem selectedContent = e.Selection.PrimarySelection;
//ContentControl element = selectedContent.View as ContentControl;
//selectedContent.Content = "hello";
selectedContent.Properties["Content"].SetValue("Hello");
}
}
这里ModelItem通过MenuActionEventArgs传递进来.当需要事务支持时,则需要用到ModelEditingScope对象,通过ModelItem的BeginEdit方法,当全部变更完成时,则调用ModelEditingScope的Complete方法.
这里可以知道ModelItem是设计器对控件做出所有的变更的一个封装,也是wpf控件设计器的一个基础.上面介绍通过Properties索引值变更视图,具体ModelItem其他的功能可以参考msdn相关文档.
3.装饰器
上图是asp.net里面GridView控件的一个设计视图,右侧的可视化面板到了wpf控件的设计时就称为装饰器,那么这个装饰器其实就是wpf的控件,实现可视化界面对于使用者而言非常重要,可以了解该控件的常用功能,也省却了一些开发时间.不过目前wpf内置控件似乎没一个控件是具有这一功能的,只能希望下版visual studio对wpf控件时做的更好了,可怕的是我们自己无法扩展内置控件的设计时,只能等着微软来做,最可怕的是visual studio 2010把wpf设计时部分的api全变掉,那么这里就全白写了.
装饰器功能由AdornerProvider提供,我们从内置提供的PrimarySelectionAdornerProvider类派生一个装饰器.
派生类需要重写以上两个方法,当选中该设计器相关控件时,会调用Activate方法,离开时调用Deactivate方法.为了介绍装饰器的使用方法.示例将尽量简单,以介绍装饰器功能.
一般情况下,装饰器需要一下几个步骤
(1)定义一个AdornerPanel对象,并把控件相关装饰器添加到AdornerPanel中,然后将这个装饰器容器添加到AdornerProvider的Adorners属性中,这项操作在Activate方法中完成.
protected override void Activate(ModelItem item, DependencyObject view)
{
Slider opacitySlider = new Slider();
opacitySlider.Background = Brushes.Red;
AdornerPanel myPanel = new AdornerPanel();
myPanel.Children.Add(opacitySlider);
Adorners.Add(myPanel);
base.Activate(item, view);
}
注意Activate方法也将ModelItem传递进来,就意味着通过装饰器的方式也可以变更控件视图
(2)定位装饰器
再来看asp.net的GridView的设计时面板,其出现在控件的右侧,wpf设计时装饰器体系允许变更装饰器位置,上面做的第一个步骤并无法在视图上看到控件的装饰器,那是因为装饰器的定位问题.这个步骤必须完成.
这项工作由AdornerPlacementCollection对象来完成,再通过AdornerPanel的静态方法SetPlacements来设置装饰器的位置.
我们来看一下AdornerPlacementCollection的几个方法,初看会比较晕,无法判断几个方法的区别
以上8个方法可以看做4个方法,都是与高度宽度有关的.下面以图来说明,我们定义的控件装饰器是一个Slider控件.目前只用于演示作用,它做不了什么其他事情.
以上是原控件,装饰器建立在此基础之上,这里说明一下上面8个方法的参数,都是一致的,第一个是倍数因子,第二个偏移量
(1)设置容器大小
为了演示,所以装饰器控件以红色背景标记,以下代码添加在Activate方法后面,SizeRelativeToContentWidth && Height方法设置装饰器容器的大小,设置宽度和高度为控件内容高度和宽度的1倍
相应代码
AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.SizeRelativeToContentHeight(1, 0); AdornerPanel.SetPlacements(opacitySlider, placement);
(2)变更装饰器位置(PositionRelativeToAdornerWidth方法),倍数参数为正数则向右移,负数则向左移
代码变更为
AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.SizeRelativeToContentHeight(1, 0);
placement.PositionRelativeToAdornerWidth(1, 0);
AdornerPanel.SetPlacements(opacitySlider, placement);
(3)DesiredWidth和DesiredHeight,注意在设计时,控件与容器之间也有着间距,如下红圈
SizeRelativeToAdornerDesiredWidth方法用于调整装饰器的DesiredWidth.看下图黄色红圈的位置变更,装饰器向右侧移动一个DesiredWidth,并宽度添加一个DesiredWidth.
代码变更为
AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.SizeRelativeToContentHeight(1, 0);
placement.PositionRelativeToAdornerWidth(1, 0);
placement.SizeRelativeToAdornerDesiredWidth(1, 0);
AdornerPanel.SetPlacements(opacitySlider, placement);
注意PositionRelativeToAdornerWidth方法变更为PositionRelativeToContentWidth方法,那么SizeRelativeToAdornerDesiredWidth方法只会使装饰器宽度变更,而位置则不做变更.如下图
代码变更为
AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.SizeRelativeToContentHeight(1, 0);
//placement.PositionRelativeToAdornerWidth(1, 0);
placement.PositionRelativeToContentWidth(1, 0);
placement.SizeRelativeToAdornerDesiredWidth(5, 0);
AdornerPanel.SetPlacements(opacitySlider, placement);
一边情况下不设置容器高度,因为控件的高度是不确定的,所以现在调整如下
现在最终代码变更为
AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.PositionRelativeToAdornerWidth(1, 0);
placement.SizeRelativeToAdornerDesiredHeight(1, 0);
AdornerPanel.SetPlacements(opacitySlider, placement);
上面方法可以做多次尝试,便于好的理解.
过年在家写的,比较乱,没有全部介绍完整.接着继续写.
wpf控件设计时支持(3)的更多相关文章
- wpf控件设计时支持(1)
原文:wpf控件设计时支持(1) 这部分内容几乎是大家忽略的内容,我想还是来介绍一下. 本篇源码下载 1.属性元数据 在vs IDE中,在asp.net,winfrom等开发环境下,右侧的Proper ...
- wpf控件设计时支持(2)
原文:wpf控件设计时支持(2) 这篇介绍在wpf设计时集合项属性添加项的定义和自定义控件右键菜单的方法 集合项属性设计时支持 1.为集合属性设计器识别具体项类型 wpf设计器允许定义集合项的类型,如 ...
- WPF解决按钮上被透明控件遮盖时无法点击问题
原文:WPF解决按钮上被透明控件遮盖时无法点击问题 IsHitTestVisible="False" 在控件上设置如上属性即可,即可让透明控件不触发点击效果
- 基于WPF系统框架设计(10)-分页控件设计
背景 最近要求项目组成员开发一个通用的分页组件,要求是这个组件简单易用,通用性,兼容现有框架MVVM模式,可是最后给我提交的成果勉强能够用,却欠少灵活性和框架兼容性. 设计的基本思想 传入数据源,总页 ...
- WPF控件获得焦点时去除虚线框
原文:WPF控件获得焦点时去除虚线框 <Setter Property="FocusVisualStyle" Value="{x:Null}" />
- 浅尝辄止——使用ActiveX装载WPF控件
1 引言 使用VC编写的容器类编辑器,很多都可以挂接ActiveX控件,因为基于COM的ActiveX控件不仅封装性不错,还可以显示一些不错的界面图元. 但是随着技术不断的进步,已被抛弃的Active ...
- 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程
反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) 背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...
- 《Dotnet9》系列-开源C# WPF控件库3《HandyControl》强力推荐
大家好,我是Dotnet9小编,一个从事dotnet开发8年+的程序员.我最近开始写dotnet分享文章,希望能让更多人看到dotnet的发展,了解更多dotnet技术,帮助dotnet程序员应用do ...
- WPF控件模板
引言:在进行WPF项目开发过程中,由于项目的需要,经常要对某个控件进行特殊的设定,其中就牵涉到模板的相关方面的内容.本文也是在自己进行项目开发过程中遇到控件模板设定时集中搜集资料后整理出来的,以供在以 ...
随机推荐
- [Angular HTML] Implementing The Input Mask Cursor Navigation Functionality -- setSelectionRange
@HostListener('keydown', ['$event', '$event.keyCode']) onKeyDown($event: KeyboardEvent, keyCode) { i ...
- java測试网络连接是否成功并设置超时时间
/** * 获取RMI接口状态 * * @return "0":服务正常,"1": 连接报错,"2":连接超时 */ @Override p ...
- EXCEL 学习笔记
上一次学院培训学生干部,讲了这个,发现自己EXCEL还是弱爆了.分享一些上次学到的东西. 1. 字符串拼接: 2.排名快速生成 RAND()随机函数 RANK(num,ref,[order]) 第一列 ...
- 删除GitHub上项目中的某个文件
原文地址 https://www.jianshu.com/p/242412b43ca5 1.首先在本地中更新有该项目的最新包 即确保本地项目和git上的项目内容保持同步(git pull拉取项目代码) ...
- 【52.49%】【codeforces 556A】Case of the Zeros and Ones
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 清楚arp
转载:http://wscyza.blog.51cto.com/898495/728717/ linux系统下清空arp 缓存(清空arp表)方法 命令红色字体标记 系统初始arp环境 [ro ...
- LSH︱python实现局部敏感随机投影森林——LSHForest/sklearn(一)
关于局部敏感哈希算法.之前用R语言实现过,可是由于在R中效能太低.于是放弃用LSH来做类似性检索.学了python发现非常多模块都能实现,并且通过随机投影森林让查询数据更快.觉得能够试试大规模应用在数 ...
- 开发自己的PHP MVC框架(一)
这个教程能够使大家掌握用mvc模式开发php应用的基本概念.此教程分为三个部分.如今这篇是第一部分. 如今市面上有非常多流行的框架供大家使用.可是我们也能够自己动手开发一个mvc框架.採用mvc模式能 ...
- Java 之 assert (断言)
我们知道C/C++语言中有断言的功能(assert).在Java SE 1.4版本以后也增加了断言的特性. 断言是为了方便调试程序,并不是发布程序的组成部分.理解这一点是很关键的. 默认情况下,JVM ...
- Python 数组[],元组(),字典{}的异同
序列 Python有6中内建的序列,在这里我们重点讨论两种,数组和元组.所有序列都可以做某些特定的操作,大致上常用的是:加,乘,索引,分片以及检查某个元素是否属于序列的成员. Python还提供一些内 ...