我正在使用WPF和.NET 3.0.
我有一个相对简单的DataTemplate定义为GridView的CellTemplate.我希望DataTemplate的VisualTree属性包含FrameworkElementFactory,但当我尝试从GridViewColumnHeader.Click事件访问它时,该属性为null.为什么VisualTree为null?我需要访问它.这是ListView定义:
<ListView ItemsSource="{Binding Stuff}" GridViewColumnHeader.Click="Header_Click">
<ListView.View>
<GridView>
<GridViewColumn Width="28">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Name="statusImage" Width="16" Height="16" Source="../Images/media_play_green_16x16.png"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Run Code Online (Sandbox Code Playgroud)
这是事件处理程序:
private void Header_Click(object sender, RoutedEventArgs e)
{
GridViewColumnHeader gvch = e.OriginalSource as GridViewColumnHeader;
// error! VisualTree is null!
//gvch.Column.CellTemplate.VisualTree.GetType();
}
Run Code Online (Sandbox Code Playgroud) 现在这可能比它的价值更麻烦但是,它现在对我来说真的很有用.
我想知道的是我如何在运行时操作Silverlight可视化树.做一些简单的事情,比如添加和删除控件都很容易,但是当你开始以任何合理的复杂度遍历树时,我发现自己渴望使用JQuery样式语法(我认为LINQ也很酷)来处理DOM节点替换,动作等.
所以我想问题是,是否有任何图书馆可以使这项工作变得更容易,或者是否有一些我错过的东西?
在WPF中,元素可以具有"可见"的可见性,但在屏幕上实际上不可见,因为它的父级(或父级的父级)具有"可见性".
我希望能够知道元素是否实际在屏幕上呈现,而不必遍历可视树检查父项.
有谁知道这样做的方法?
提前致谢!
我有ItemsControl和Grid作为ItemsPanelTemplate
<ItemsControl ItemsSource="{Binding CellCollection}" Name="CellGrid">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid Name="grid" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
我在代码隐藏中使用此ItemControl创建了一些UserControl,然后我需要创建RowDefinitions和ColumnDefinitons.我使用这种方法得到"网格":
private TChildItem FindVisualChild<TChildItem>(DependencyObject obj) where TChildItem : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
var child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is TChildItem)
return (TChildItem)child;
var childOfChild = FindVisualChild<TChildItem>(child);
if (childOfChild != null)
return childOfChild;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我在显示UserControl之前调用此方法它返回null,所以我无法找到访问"网格",当UserControl出现时它显示不像我预期的那样.
我试图谷歌,但我发现的是假设VisualTree没有为ItemControl构建,直到它在表单上显示.
有什么建议?谢谢,抱歉英文不好;)
我试图从DataTemplate获取我的SelectedRadioButton.
Wpf Inspector展示了Visual Tree:

并在代码中:
void menu_StatusGeneratorChanged(object sender, EventArgs e)
{
var status = Menu.Items.ItemContainerGenerator.Status;
if (status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
{
var item = Menu.Items.ItemContainerGenerator.ContainerFromIndex(0);
// item is a ContentPresenter
var control = Tools.FindChild<SelectedRadioButton>(item);
control = Tools.FindAncestor<SelectedRadioButton>(item);
}
}
Run Code Online (Sandbox Code Playgroud)
item是一个ContentPresenter,看到Wpf检查器的图像,我相信从那里我必须能够到达SelectedRadioButton.变量control始终为null.
我在这里错过了什么?我使用这些visualtreehelpers.
在WPF应用程序中,如果在XAML中声明了ContentControl,
<Grid Name="MyGrid">
<ContentControl Name="MyContentControl" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
然后我可以使用FindName以下代码在代码中轻松引用它
ContentControl cc = FindName("MyContentControl") as ContentControl;
cc.Content = ...
Run Code Online (Sandbox Code Playgroud)
但是,如果我在代码中添加ContentControl:
ContentControl contentcntr = new ContentControl();
contentcntr.Name = "MyContentControl";
this.MyGrid.Children.Add(contentcntr);
Run Code Online (Sandbox Code Playgroud)
在FindName没有找到它.
在第二种情况下它有什么问题?有什么不同?
我将重点放在Popup的开头:
wcl:FocusHelper.IsFocused="{Binding RelativeSource={RelativeSource Self}, Path=IsOpen}"
Run Code Online (Sandbox Code Playgroud)
FocusHelper类代码:
public static class FocusHelper
{
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached("IsFocused", typeof(bool?), typeof(FocusHelper), new FrameworkPropertyMetadata(IsFocusedChanged));
public static bool? GetIsFocused(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (bool?)element.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(DependencyObject element, bool? value)
{
if (element == null)
throw new ArgumentNullException("element");
element.SetValue(IsFocusedProperty, value);
}
private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var fe = (FrameworkElement)d;
if (e.OldValue == null)
{
fe.GotFocus += ElementGotFocus;
fe.LostFocus += …Run Code Online (Sandbox Code Playgroud) 在以下屏幕截图中,AdornerLayer已添加到AdornerDecorator中,Adorners(MyAdorners)将添加到此AdornerLayer中.但AdornerLayer是这样检索的,
AdornerLayer layer1 = AdornerLayer.GetAdornerLayer(button1);
layer1.Add(new MyAdorner(button1));
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) 在可视化树中我可以找到ComboBox弹出窗口(带有ComboBoxItems的列表)?
我已经以编程方式打开了一个ComboBox,当在调试器中的WPF Tree Visualizer中观察它时,我看到以下内容:
: ComboBox
templateRoot : Grid
PART_Popup : Popup
toggleButton : ToggleButton
templateRoot : Border
splitBorder : Border
Arrow : Path
contentPresenter : ContentPresenter
: TextBlock
Run Code Online (Sandbox Code Playgroud)
我希望看到ScrollViewer带有某种物品主机(StackPanel?),也许是PART_Popup所在的地方,但什么都没有.
那它在哪里?
visual-tree ×10
wpf ×9
c# ×5
xaml ×2
adorner ×1
adornerlayer ×1
binding ×1
celltemplate ×1
combobox ×1
datatemplate ×1
itemscontrol ×1
logical-tree ×1
popup ×1
silverlight ×1
visibility ×1