我有一个控件是另一个控件的子控件(因为所有非root控件/元素都在WPF中).如果我想将控件移动到另一个容器,我必须先将它与当前容器断开连接(否则抛出异常).
如果我知道父母是什么,那么我可以将它从其儿童收藏品,内容或其他内容中删除.但是,如果我不知道父容器的类型是什么 - 如何删除子控件呢?
在下面的代码示例中:如何在不知道父类型(Panel,GroupBox ...)的情况下将"sp1"移动到另一个容器?
// Add the child object "sp1" to a container (of any type).
StackPanel sp1 = new StackPanel();
SomeParentControl.Children.Add(sp1);
// Somewhere else in the code. I still have a reference to "sp1" but now I don't know what container it is in. I just want to move the "sp1" object to another parent container.
AnotherParentControl.Content = sp1; // Generates exception: "Must disconnect specified child from current parent Visual before attaching to new parent Visual."
Run Code Online (Sandbox Code Playgroud)
理想情况下,我只想写一些类似的东西: …
有{Binding ElementName=foo},它会查找视觉或逻辑树吗?
逻辑树什么时候重要?
当查找名称时,例如在{Binding ElementName = Foo}中,搜索会向祖先寻找名称范围,就像对可继承属性一样.
Silverlight中的ElementName绑定通过附加行为
为了实现这一点,WPF提供了ElementName和RelativeSource绑定,为您提供了一种强大的机制,用于定位可视树中要绑定的其他元素.
编辑:
它看起来像用于绑定的逻辑树ElementName.
争论#1.
根据MSDN文章FrameworkElement类:
FrameworkElement扩展了UIElement并添加了以下功能:
- 支持数据绑定和动态资源引用:对数据绑定和资源的属性级支持由DependencyProperty类实现并体现在属性系统中,但是能够解析存储为Expression的成员值(编程构造) FrameworkElement实现了数据绑定和动态资源的基础.有关更多信息,请参阅数据绑定概述和资源概述.
争论#2.
ElementName指向x:Name,所以这个名字应该找到一些如何.有一个NameScope概念.
对于大多数情况,在FrameworkElement和FrameworkContentElement上公开的FindName方法是调用按名称搜索元素的更合适的方法.FrameworkElement和FrameworkContentElement公开的Name属性是用于将初始名称设置为标记属性的更合适的属性.并且在FrameworkElement和FrameworkContentElement上公开的RegisterName方法对于在特定的名称范围内建立名称是必要的(没有可以直接执行此操作的NameScope成员;您必须首先将当前的namescope设置为使用RegisterName).
另一方面,Visual类既没有FindName方法也没有实现INameScope.
我理解Visual和logical树的概念,但我仍然无法理解这些的真正用途和需要.虽然没有必要知道这些树的一切,但我相信它会在一些高级场景中受益.
我已经阅读了以下文章并理解了这些概念
http://www.codeproject.com/KB/WPF/WpfElementTrees.aspx
http://blogs.msdn.com/b/mikehillberg/archive/2008/05/23/of-logical-and-visual-trees-in-wpf.aspx
我想要理解的是在框架内使用这些(简单的单词和易于理解的场景)?你究竟何时想出何时使用视觉或逻辑树?有助于可视化这些树的任何其他信息?
我有一个逻辑表达式,我想评估.表达式可以嵌套,由T(True)或F(False)和括号组成.括号"("表示"逻辑或".彼此旁边的两个术语TF(或彼此旁边的任何其他两个组合)应该是ANDED(逻辑与).
例如,表达式:
((TFT)T) = true
Run Code Online (Sandbox Code Playgroud)
我需要一个算法来解决这个问题.我想到首先将表达式转换为析取或连接的正规形式,然后我可以轻松地评估表达式.但是,我找不到一个规范化表达式的算法.有什么建议?谢谢.
问题陈述可以在这里找到:https: //icpcarchive.ecs.baylor.edu/index.php?option = com_onlinejudge&Itemid = 2&category = 378&page = show_problem&issueble = 2967
编辑:我误解了部分问题.在给定的逻辑表达式中,AND/OR运算符与每个括号"(")交替.如果我们要通过树表示表达式,则AND/OR运算符取决于子树的深度级别.但是,它是最初认为最深层的树是AND树.我的任务是通过构建树来评估给定的表达式.感谢下面的答案,澄清了问题的正确要求.
我有一个问题,DataContextChanged没有在我的自定义Panel控件的逻辑子上引发.我把它缩小到这个:
从向导生成的WPF应用程序开始,我添加:
private void Window_Loaded( object sender, RoutedEventArgs e )
{
var elt = new FrameworkElement();
this.AddLogicalChild( elt );
DataContext = 42;
Debug.Assert( (int)elt.DataContext == 42 );
}
Run Code Online (Sandbox Code Playgroud)
据我所知,这是有效的,因为DataContext是一个可继承的依赖属性.
现在,我在Window(this)及其逻辑子代上为DataContextChanged添加事件处理程序:
this.DataContextChanged +=
delegate { Debug.WriteLine( "this:DataContextChanged" ); };
elt.DataContextChanged +=
delegate { Debug.WriteLine( "elt:DataContextChanged" ); };
Run Code Online (Sandbox Code Playgroud)
如果我运行它,只会执行第一个事件处理程序.为什么是这样?如果不是AddLogicalChild(elt),我会执行以下操作:
this.Content = elt;
Run Code Online (Sandbox Code Playgroud)
两个处理程序都将执行.但是在我的情况下这不是一个选项 - 我正在向我的控件中添加FrameworkContentElements,它们不应该是可视化的孩子.
这里发生了什么?除了AddLogicalChild()之外,我还应该做些什么来使它工作吗?
(幸运的是,有一个相当简单的解决方法 - 只需将元素的DataContext绑定到窗口的DataContext)
BindingOperations.SetBinding( elt, FrameworkElement.DataContextProperty,
new Binding( "DataContext" ) { Source = this …Run Code Online (Sandbox Code Playgroud) 假设我有两个可以引用第三个UI对象的类(在本例中是一个按钮).
此外,父类可以包含子类的元素.
如果它们都以相同的方式绑定到同一个控件,则子节点会失败但父节点会成功.
父母:
class MyFrameworkElement : FrameworkElement
{
// A depenedency property that will contain a child element sub-element
private static readonly DependencyProperty ChildElementProperty =
DependencyProperty.Register("ChildElement",
typeof(MyChildElement),
typeof(MyFrameworkElement),
new PropertyMetadata());
[Category("ChildProperties")]
public MyChildElement ChildElement
{
set { SetValue(ChildElementProperty, value); }
get { return (MyChildElement)GetValue(ChildElementProperty); }
}
// Now, a reference to some other control, in this case we will bind a button to it!
public UIElement ButtonReferenceInParent
{
get { return (UIElement)GetValue(ButtonReferenceInParentProperty); }
set { SetValue(ButtonReferenceInParentProperty, value); …Run Code Online (Sandbox Code Playgroud) logical-tree ×6
wpf ×5
visual-tree ×3
binding ×2
.net ×1
algorithm ×1
c# ×1
datacontext ×1
elementname ×1
tree ×1
xaml ×1