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 ...
随机推荐
- 挖一挖不经常使用到而又非常有用的重载-Split
Split这个基本上全部的程序开发者都用到,一般使用单字符和长字符串拆分字符串的较多.事实上另一个重载很好用.那就是多种组合字符来进行拆分. 比如: "aaaaaaaaaa{@}bbbbbb ...
- cookie和session使用
cookie和session使用 一.总结 1.需要使用的场景:验证用户是否登录时 获取用户的用户名时 退出登录时 2.cookie和session在什么时候记录:在登录成功之后 二.cook ...
- UVA - 1161 Objective: Berlin(最大流+时序模型)
题目大意:有n个城市m条航线.给出每条航线的出发地,目的地,座位数,起飞时间和到达时间(所给形式为HHMM.记得转化),再给出城市A和B.和到达城市B的最晚时间.如今问一天内最多有多少人能从A飞到B, ...
- swift开发网络篇 - 用户登录POST JSON and header
版权声明:本文为博主原创文章,未经博主允许不得转载. import UIKit import Alamofire class ViewController: UIViewController { va ...
- MacBook Touch Bar 使用技巧
MacBook Touch Bar 使用技巧 使用Clock Bar再Touch Bar上显示时间 在全屏显示的情况下无法看到时间,于是就想在Touch Bar上是否可以显示时间呢,系统好像没有相应的 ...
- POJ 1458 Common Subsequence (zoj 1733 ) LCS
POJ:http://poj.org/problem?id=1458 ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=73 ...
- sublime text2 基本配置及结合Python 环境
参考: http://www.cnblogs.com/figure9/p/sublime-text-complete-guide.html http://www.zhihu.com/question/ ...
- 【BZOJ 3675】[Apio2014]序列分割
[链接] 链接 [题意] 在这里输入题意 [题解] 模拟一下样例. 会发现.切的顺序不影响最后的答案. 只要切点确定了. 答案就确定了. 则设f[i][j]表示前i段,第i段保留到j的最大值. \(f ...
- cocos2d-x游戏开发 跑酷(九) 源代码下载及小结
这个东西零零碎碎写了一个礼拜吧. 事实上也没多少东西在里面.文章后附下载地址 博客地址:http://blog.csdn.net/dawn_moon 由于我没用过chipmunk,并且它是面向过程的东 ...
- 一段代码的疑问(1)——unsigned与signed
现象: 先来看一段代码: 这段代码的输出结果是: -84 4294967264 分析: xiaoqiang@dev:~/cpp$ g++ -g c212.cc -o temp xiaoqiang@de ...