1.适用场景:获得listBox的Item的ControlTemplate中的元素控件
c#后台文件
/// <summary>
/// 通过Tree 寻找控件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="childName"></param>
/// <returns></returns>
public T FindFirstVisualChild<T>(DependencyObject obj, string childName) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T && child.GetValue(NameProperty).ToString() == childName)
{
return (T)child;
}
else
{
T childOfChild = FindFirstVisualChild<T>(child, childName);
if (childOfChild != null)
{
return childOfChild;
}
}
}
return null;
}
Resource文件
<Style x:Key="MyDeskTopListBoxItemStyle"
TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid Background="{TemplateBinding Background}"> <Grid x:Name="grdSelect">
<ctrl:ImageButton x:Name="btnMouseClose"
ImageNormal="/SLClient.Styles;component/Images/newDesktopClose_normal.png"
ImageOver="/SLClient.Styles;component/Images/newDesktopClose_hover.png"
Style="{StaticResource ImageButtonStyle}"
Grid.Column="2" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
调用方式:
for (int i = 0; i < lstMyDesktop.Items.Count; i++)
{
System.Windows.Controls.ListBoxItem lstselectedItem = (System.Windows.Controls.ListBoxItem)(lstMyDesktop.ItemContainerGenerator.ContainerFromItem(lstMyDesktop.Items[i]));
ImageButton myImgBtn = FindFirstVisualChild<ImageButton>(lstselectedItem, "btnClose");
}
或者
//setting 是一个实体
MyDesktopSetting setting = new MyDesktopSetting();
System.Windows.Controls.ListBoxItem lstselectedItem = (System.Windows.Controls.ListBoxItem)(lstMyDesktop.ItemContainerGenerator.ContainerFromItem(setting));
ImageButton addImgBtn = FindFirstVisualChild<ImageButton>(lstselectedItem, "btnClose");
注意问题:
可能通过 ListBoxItem lstselectedItem = (System.Windows.Controls.ListBoxItem)(lstMyDesktop.ItemContainerGenerator.ContainerFromItem(setting));
获得值为空,那么需要在ListBox的Loaded事件中调用如上代码。
也可以在ListBoxe的.ItemContainerGenerator.StatusChanged事件中调用。如果在此事件中仍获得不到listBoxItem的值,则异步调用即可获得值。代码:
private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
if (lstWall.ItemContainerGenerator.Status !=
System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) return;
lstWall.ItemContainerGenerator.StatusChanged -= ItemContainerGenerator_StatusChanged;
Action action = () =>
{
SetHide(m_CurrentWallSpeed);
SetOpacity(m_CurrentWallSpeed);
SetZeroOpacity(m_CurrentWallSpeed);
};
Dispatcher.BeginInvoke(DispatcherPriority.Background, action);
}
上述两个事件因不同需求各自使用。