WPF是否有办法在MouseMove事件上获取鼠标下的元素数组?
有{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.
我希望有一个WPF容器(面板,用户控件等)公开一个属性,以便将所有子项设置为只读(如果已设置).这应该就像将父控件设置为IsEnabled = false,这也会禁用所有子节点.应该考虑哪些孩子及其属性是固定的(例如TextBox.ReadOnly,DataGrid.ReadOnly,...).
我试图创建这样一个控件,它基本上迭代了可视树的所有子项(递归)并相应地处理控件.
这种方法很好,除了进一步更改会影响可视树的情况,以便添加新的子项.这对于ContentControl或ItemsControl都是如此.如果孩子们在浏览完它们后被添加到可视化树中,它们显然不是只读的.
我试图找到一个好的事件来做出反应(基本上在视觉树中检测新的孩子),但是找不到合适的东西.UpdateLayout被触发,但每次都经常通过可视树.
有办法解决这个问题吗?是否有另一种方法可以通过父元素上的绑定将所有(相关)子节点递归设置为只读?
(并且不会:我不希望将所有子项只读属性绑定到全局绑定.重点是将一个元素/部分传播给所有子节点)
我想从可视化树中删除FrameworkElement.由于FrameworkElement具有Parent属性,因此通过从那里删除它来解决此问题是显而易见的:
FrameworkElement childElement;
if(childElement != null && childElement.Parent != null) // In the visual tree
{
// This line will, of course not complie:
// childElement.Parent.RemoveFromChildren(childElement);
}
Run Code Online (Sandbox Code Playgroud)
问题是FrameworkElement的Parent属性是DependencyObject,它没有子节点的概念.所以我唯一可以看到的问题就是通过强制转换父级来查看它是否是边框,面板等(具有子级概念的元素)并从那里删除它:
FrameworkElement childElement;
if(childElement != null && childElement.Parent != null) // In the visual tree
{
if(childElement.Parent is Panel)
{
(childElement.Parent as Panel).Children.Remove(childElement );
}
if(childElement.Parent is Border)
{
(childElement.Parent as Border).Child = null;
}
}
Run Code Online (Sandbox Code Playgroud)
显然,这不是一个非常灵活的解决方案,根本不是通用的.有人可以建议一种更通用的方法从视觉树中删除元素吗?
有时右键单击treeviewitem结果未处理InvalidOperationException.在后面的代码中,我选择右键单击的行:
static TreeViewItem VisualUpwardSearch(DependencyObject source)
{
while (source != null && !(source is TreeViewItem))
source = VisualTreeHelper.GetParent(source);
return source as TreeViewItem;
}
private void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject);
if (treeViewItem != null)
{
treeViewItem.Focus();
e.Handled = true;
}
}
Run Code Online (Sandbox Code Playgroud)
根据stacktrace,上面是问题的根源.
XAML:
<UserControl.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding ClassesItemsSource}" DataType="{x:Type pnls:FavoriteObjectTableViewModel}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Converter={StaticResource nameToBitmapSource}}" DataContext="{Binding Bitmap}" />
<Label Content="{Binding TableName}"/>
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type pnls:FavoriteObjectClassViewModel}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Bitmap, Converter={StaticResource UriToCachedImageConverter}}"/>
<Label Content="{Binding …Run Code Online (Sandbox Code Playgroud) 根据一些自定义安全设置,我将窗口子控件更改为只读和禁用.为了实现这一点,我在窗口加载时循环访问子控件.
这很好用.99%完美.
在我的窗口中,我有一个ItemsControl,其内容基于ComboBox.更改ComboBox,ItemsControl中的子控件再次进行数据绑定.但是,安全性(只读/禁用)不再适用.
在你跳转到解决方案之前,我知道我可以处理ComboBox更改的事件; 但是,我有很多这样的盒子和Wnt一个通用的解决方案,可以在窗口级应用(认为:基地)无论什么我的开发人员添加到窗口/形式.
我的问题(对于长期的引导而言)是,如何通过像数据绑定这样的动态活动来检测何时将新子项添加到窗口中?是否有NewChildAdded事件?是否有DataBindingJustChangedThings事件?
必须有所作为.
如果您的解决方案包含计时器,则无需回复.我的表单太复杂,无法处理额外的负载 - 而且刻度之间的延迟实际上是一个安全问题.
你可能会想,只是让外部容器只读或禁用.但这会对扩展器,多行文本框和列表框等内容产生负面影响.这种方法不够细致.当然,这是我们之前开始迭代的地方.
如果您的解决方案包含样式,则需要包括如何在每个控件的基础上覆盖您的方法.某些控件(如复选框)无法禁用,因为它们在UI布局中有用途.
很抱歉有限制,但我打算在生产中使用该解决方案.
谢谢.
我无法在Visual Studio 2017中为UWP应用程序(C#)启用Live Visual Tree.这个工具正在开发VS2015,但在VS2017中从未为我工作过.它对我的WPF项目没有任何问题.
我收到以下错误消息Live Visual Tree:
UI调试需要最新版本的SDK和通用Windows应用程序开发工具.确保已安装这些工具以启用UI调试.
我尝试了什么:
Enable UI Debugging Tools for XAML已签入Options/Debugging.Windows 10 SDK (10.0.15063.0) for UWP: C#, VB, JS我无法在网络或Stack Overflow中找到有关该问题的任何信息(与VS 2017相关,尽管在VS2015中找到了一些信息).请帮忙.
在WPF应用程序中,我想将UserControl从ContentControl移动到代码中的另一个:
myContentControl2.Content = myUserControl;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我得到一个错误:
指定的元素已经是另一个元素的逻辑子元素.首先断开它.
在ControlControl类描述中,我可以看到RemoveVisualChild方法,但是当我尝试在代码中使用它时,我得到一个Unknown方法错误
myContentControl1.RemoveVisualChild(myUserControl);//here I get an "Unknown method" error
Run Code Online (Sandbox Code Playgroud)
我哪里错了?
如何将UserControl从ContentControl移动到代码隐藏中的另一个?
如何提取 ListBoxItem 的父容器?在下面的例子中,我可以去到 ListBoxItem,比它更高,我什么都没有:
<ListBox Name="lbAddress">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Click="Button_Click"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
Private Sub Button_Click(sender As Button, e As RoutedEventArgs)
Dim lbAddress = GetAncestor(Of ListBox) 'Result: Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)
Public Shared Function GetAncestor(Of T)(reference As DependencyObject) As T
Dim parent = GetParent(reference)
While parent IsNot Nothing AndAlso Not parent.GetType.Equals(GetType(T))
parent = GetAncestor(Of T)(parent)
End While
If parent IsNot Nothing Then _
Return If(parent.GetType Is GetType(T), parent, Nothing)
Return Nothing
End Sub
Public Function GetParent(reference As DependencyObject) As DependencyObject
Dim …Run Code Online (Sandbox Code Playgroud) 我理解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
我想要理解的是在框架内使用这些(简单的单词和易于理解的场景)?你究竟何时想出何时使用视觉或逻辑树?有助于可视化这些树的任何其他信息?
visual-tree ×10
wpf ×9
c# ×3
logical-tree ×2
.net ×1
binding ×1
children ×1
element ×1
elementname ×1
events ×1
listbox ×1
listboxitem ×1
silverlight ×1
xaml ×1