我有一个通过ItemsControl
显示的超链接列表,如下所示:
<ItemsControl x:Name="SubMenu" Visibility="Collapsed">
<ItemsControl.ItemTemplate>
<DataTemplate>
<HyperlinkButton Content="{Binding Name}"
NavigateUri="{Binding Url}"
TargetName="ContentFrame"
Style="{StaticResource LinkStyle}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Style="{StaticResource LinksStackPanelStyle}"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我需要做的是枚举子菜单中的实际超链接,如下所示:
foreach (UIElement child in SubMenu.Items) // this does not work!
{
HyperlinkButton hb = child as HyperlinkButton;
if (hb != null && hb.NavigateUri != null)
{
if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
{
VisualStateManager.GoToState(hb, "ActiveLink", true);
}
else
{
VisualStateManager.GoToState(hb, "InactiveLink", true);
}
}
}
问题是我似乎找不到枚举ItemsCollection.Items中实际UI元素的方法。
任何人都知道如何执行此操作或可能的解决方法?
我可以提一下,我想要做的是建立一个菜单和子菜单,显示点击的超链接作为一种面包屑。
更新 最好的办法是,如果我能以某种方式到达那个堆栈面板,因为这段代码似乎有效:
foreach (UIElement child in LinksStackPanel.Children)
{
HyperlinkButton hb = child as HyperlinkButton;
if (hb != null && hb.NavigateUri != null)
{
if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
{
VisualStateManager.GoToState(hb, "ActiveLink", true);
}
else
{
VisualStateManager.GoToState(hb, "InactiveLink", true);
}
}
}
答案 0 :(得分:8)
解决方案如下所示:
foreach (var item in SubMenu.Items)
{
var hb = SubMenu.ItemContainerGenerator.ContainerFromItem(item).FindVisualChild<HyperlinkButton>();
if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
{
VisualStateManager.GoToState(hb, "ActiveLink", true);
}
else
{
VisualStateManager.GoToState(hb, "InactiveLink", true);
}
}
扩展方法FindVisualChild:
public static T FindVisualChild<T>(this DependencyObject instance) where T : DependencyObject
{
T control = default(T);
if (instance != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(instance); i++)
{
if ((control = VisualTreeHelper.GetChild(instance, i) as T) != null)
{
break;
}
control = FindVisualChild<T>(VisualTreeHelper.GetChild(instance, i));
}
}
return control;
}
答案 1 :(得分:2)
尝试使用ItemContainerGenerator.ContainerFromItem方法
foreach (var item in SubMenu.Items)
{
var child = SubMenu.ItemContainerGenerator.ContainerFromItem(item);
HyperlinkButton hb = child as HyperlinkButton;
// use hb
}
答案 2 :(得分:2)
这是固定版本。
public static T FindVisualChild<T>(this DependencyObject instance) where T : DependencyObject
{
T control = default(T);
if (instance != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(instance); i++)
{
if ((control = VisualTreeHelper.GetChild(instance, i) as T) != null)
{
break;
}
if ((control = FindVisualChild<T>(VisualTreeHelper.GetChild(instance, i))) != null)
{
break;
}
}
}
return control;
}
答案 3 :(得分:1)
试试这个:
foreach (UIElement child in SubMenu.Items.OfType<UIElement>())
这是使用Enumerable.OfType<TResult>
扩展方法将集合过滤到仅指定类型的项目。