WPF的两棵树与绑定
原文:WPF的两棵树与绑定
先建立测试基类
public class VisualPanel : FrameworkElement
{
protected VisualCollection Children { get; set; } public VisualPanel()
{
Children = new VisualCollection(this);
} protected override int VisualChildrenCount
{
get
{
return Children.Count;
}
} protected override Visual GetVisualChild(int index)
{
return Children[index];
} protected override Size ArrangeOverride(Size finalSize)
{
if (VisualChildrenCount>0)
{
(Children[0] as FrameworkElement).Arrange(new Rect(0, 0, 100, 25));
}
return base.ArrangeOverride(finalSize);
}
}
添加元素,并将加入到Window窗体中
public class VisualTest : VisualPanel
{
public TextBlock textblock; private void TestVisual()
{
textblock = new TextBlock() { Text = "Hello", Background = Brushes.Red };
this.Children.Add(textblock);
} public VisualTest()
{
TestVisual();
}
}
效果
视觉树绑定测试
//test1
textblock.SetBinding(TextBlock.TextProperty, new Binding("Title")
{
RelativeSource =
new RelativeSource() { Mode = RelativeSourceMode.FindAncestor, AncestorType = typeof(Window) }
});
//test2
this.Tag = "Test";
textblock.SetBinding(TextBlock.TextProperty, new Binding("Tag")
{
RelativeSource =
new RelativeSource() { Mode = RelativeSourceMode.FindAncestor, AncestorType = typeof(VisualTest) }
});
测试均通过
使用ElementName绑定
//test3
this.Name = "VisualTest"; textblock.SetBinding(TextBlock.TextProperty, new Binding("Tag")
{
ElementName = this.Name
});
可以参考这里
http://www.cnblogs.com/Clingingboy/archive/2010/11/29/1891253.html
结果错误
设置NameScope
this.Name = "VisualTest";
NameScope ns = new NameScope();
NameScope.SetNameScope(this, ns);
this.RegisterName(this.Name, this);
textblock.SetBinding(TextBlock.TextProperty, new Binding("Tag")
{
ElementName = this.Name
});
测试再次未通过
将元素添加到逻辑树当中
this.Name = "VisualTest";
NameScope ns = new NameScope();
NameScope.SetNameScope(this, ns);
this.RegisterName(this.Name, this);
AddLogicalChild(textblock);
textblock.SetBinding(TextBlock.TextProperty, new Binding("Tag")
{
ElementName = this.Name
});
测试通过
去除视觉树只添加逻辑树的情况
private void TestLogic()
{
textblock = new TextBlock() { Text = "Hello", Background = Brushes.Red };
this.Tag = "Test";
this.Name = "VisualTest";
NameScope ns = new NameScope();
NameScope.SetNameScope(this, ns);
this.RegisterName(this.Name, this);
AddLogicalChild(textblock);
textblock.SetBinding(TextBlock.TextProperty, new Binding("Tag")
{
ElementName = this.Name
});
}
现在UI将一片空白,但绑定成功
重写ArrangeOverride方法
protected override Size ArrangeOverride(Size finalSize)
{
textblock.Arrange(new Rect(0, 0, 100, 25));
return base.ArrangeOverride(finalSize);
}
即使重写也无效,wpf依赖于VisualChildrenCount和GetVisualChild方法.
总结
绑定的ElementName依赖于NameScope和逻辑树,
FindAncestor的查找方式则依赖于视觉树
测试的父元素逻辑树与视觉树不一致的情况
private void TestTwoTree()
{
var visual = new VisualTest(string.Empty);
visual.Name = "InternalPanel";
textblock = new TextBlock() { Text = "Hello", Background = Brushes.Red };
visual.AddLogicalChild(textblock);
this.Children.Add(textblock);
}
现在TextBlock有两个父元素一个是逻辑父元素InternalPanel,一个是外部的VisualTest.
绑定逻辑父元素
private void TestTwoTree()
{
var visual = new VisualTest(string.Empty);
visual.Name = "InernalPanel";
NameScope ns = new NameScope();
NameScope.SetNameScope(visual, ns);
visual.RegisterName(visual.Name, visual);
textblock = new TextBlock() { Text = "Hello", Background = Brushes.Red };
textblock.SetBinding(TextBlock.TextProperty, new Binding("Name")
{
ElementName = visual.Name
});
visual.AddLogicalChild(textblock);
this.Children.Add(textblock);
}
测试结果
这样就实现了可以在不同父元素的绑定,通过这个例子也可以看到逻辑树与视觉树的不同之处
WPF的两棵树与绑定的更多相关文章
- LeetCode——Same Tree(判断两棵树是否相同)
问题: Given two binary trees, write a function to check if they are equal or not. Two binary trees are ...
- element ui改写实现两棵树
使用element ui组件库实现一个table的两棵树的效果 效果如下,左边树自动展开一级,右边树默认显示楼层,然后可以一个个展开 代码如下 <el-table :data="rel ...
- [51nod1325]两棵树的问题
description 题面 solution 点分治+最小割. 点分必选的重心,再在树上dfs判交,转化为最大权闭合子图. 可以做\(k\)棵树的情况. code #include<iostr ...
- 51 NOD 1325 两棵树的问题
Discription 对于 100% 的数据, N<=50. solution: 发现N比较小,所以我们可以花O(N^2)的代价枚举两颗树的联通块的LCA分别是哪个点,然后现在问题就变成了:选 ...
- 51nod 1325 两棵树的问题(最大权闭合子图)
首先如果点权全都为正,就可以直接选所有的点. 活在梦里.. 考虑枚举一个点\(i\),作为我们选择的集合中的一个点. 然后我们把另一个点\(j\)选入集合的时候必须把两棵树中\(i\)和\(j\)路径 ...
- HDU 6315.Naive Operations-线段树(两棵树合并)(区间单点更新、区间最值、区间求和)+思维 (2018 Multi-University Training Contest 2 1007)
6315.Naive Operations 题意很好理解,但是因为区间求和求的是向下取整的a[i]/b[i],所以直接分数更新区间是不对的,所以反过来直接当a[i]==b[i]的时候,线段树对应的位置 ...
- 判断两棵树是否相等 leecode
很简单 提交代码 https://oj.leetcode.com/problems/same-tree/ iven two binary trees, write a function to chec ...
- WPF 中的逻辑树(Logical Tree)与可视化元素树(Visual Tree)
一.前言 WPF 中有两种"树":逻辑树(Logical Tree)和可视化元素树(Visual Tree). Logical Tree 最显著的特点就是它完全由布局组件和控件 ...
- hdu-3015 Disharmony Trees---离散化+两个树状数组
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3015 题目大意: 有一些树,这些树的高度和位置给出.现在高度和位置都按从小到大排序,对应一个新的ra ...
随机推荐
- 第三方插件将数据转成json
1.需要使用第三方jar commons-beanutils-1.7.0.jar /commons-collections-3.1.jar/commons-lang-2.5jar /commons-l ...
- 如何在Win8/Win10上开启 dotNetFramework 2.0/3.5 功能
问题: 在Windows 8.Windows 10上安装一些软件时,系统可能会报出如下错误:你的电脑上的应用需要使用以下Windows功能: 解决方式: 首先呢,你需要准备好一个Win8/ ...
- RDA安装
解压到/home/oracle下面 $ cp /home/oracle/rda $ perl rda.pl -cv 运行上面的命令,如果最后一行出现下面所示,说明没问题 No ...
- HDU 1280 前m大的数 基数排序
http://acm.hdu.edu.cn/showproblem.php?pid=1280 题目大意: 给你N(N<=3000)个数(这些数不超过5000),要求输出他们两两相加后和最大的M( ...
- C语言编程程序的内存怎样布局
在c语言中,每一个变量和函数有两个属性:数据类型和数据的存储类别. C语言中局部变量和全局变量变量的存储类别(static,extern,auto,register) 1. 从变量的作用域划分变量(即 ...
- SDI与ASI 接口具体解释介绍
分量编码 在对彩色电视信号进行数字化处理和传输是.一种经常使用的方式是分别对其3个分量(Y,R-Y.B-Y)进行数字化编码.这就是分量分量编码.另外还有全信号编码,全信号编码是对彩色全电视信号直接进行 ...
- Android自定义组件系列【9】——Canvas绘制折线图
有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas ...
- 使用oschina的gitserver
1.概要 事实上oschina的gitserver与github的几乎相同.只是既然是中国的gitserver,那么速度应该更快一些吧 2.注冊 链接https://git.oschina.net/, ...
- Spring mvc redirect跳转路径问题
SpringMVC重定向视图RedirectView小分析 前言 SpringMVC是目前主流的Web MVC框架之一. 本文所讲的部分内容跟SpringMVC的视图机制有关,SpringMVC的视图 ...
- 【t077】宝物筛选
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物--这下小FF可发财了.但是这里的宝物实在是太多 ...