Xaml如下:
代码
<
UserControl
x:Class
="ToolsTest.Test"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
Width ="400" Height ="300" >
< UserControl.Resources >
< DataTemplate x:Key ="dt" >
< TextBlock Padding ="5,0,5,0" Text =" {Binding d} " x:Name ="myTxt" />
</ DataTemplate >
</ UserControl.Resources >
< StackPanel >
< ListBox Name ="myListBox" ItemTemplate =" {StaticResource dt} " />
< Button Content ="查找myTxt" x:Name ="btnFind" Width ="90" Click ="btnFind_Click" ></ Button >
</ StackPanel >
</ UserControl >
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
Width ="400" Height ="300" >
< UserControl.Resources >
< DataTemplate x:Key ="dt" >
< TextBlock Padding ="5,0,5,0" Text =" {Binding d} " x:Name ="myTxt" />
</ DataTemplate >
</ UserControl.Resources >
< StackPanel >
< ListBox Name ="myListBox" ItemTemplate =" {StaticResource dt} " />
< Button Content ="查找myTxt" x:Name ="btnFind" Width ="90" Click ="btnFind_Click" ></ Button >
</ StackPanel >
</ UserControl >
Xaml.cs如下:
代码
using
System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace ToolsTest
{
public partial class Test : UserControl
{
ObservableCollection < TestData > oc;
public Test()
{
InitializeComponent();
this .Loaded += new RoutedEventHandler(Test_Loaded);
}
void Test_Loaded( object sender, RoutedEventArgs e)
{
oc = new ObservableCollection < TestData > ();
oc.Add( new TestData() { d = " A " });
oc.Add( new TestData() { d = " B " });
this .myListBox.ItemsSource = oc;
}
private void btnFind_Click( object sender, RoutedEventArgs e)
{
if (myListBox.SelectedItem != null )
{
ListBoxItem _selectedItem = (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.SelectedItem));
TextBlock myTxt = FindFirstVisualChild < TextBlock > (_selectedItem, " myTxt " );
MessageBox.Show( string .Format( " 选中行的TextBlock值为: " + myTxt.Text));
}
ListBoxItem _firstItem = (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items[ 0 ]));
// var t = _firstItem.FindName("myTxt"); // 这样是找不到的
TextBlock myTxtFirst = FindFirstVisualChild < TextBlock > (_firstItem, " myTxt " );
MessageBox.Show( string .Format( " 第一行的TextBlock值为: " + myTxtFirst.Text));
}
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 ;
}
}
public class TestData{ public string d{ set ; get ;}}
}
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace ToolsTest
{
public partial class Test : UserControl
{
ObservableCollection < TestData > oc;
public Test()
{
InitializeComponent();
this .Loaded += new RoutedEventHandler(Test_Loaded);
}
void Test_Loaded( object sender, RoutedEventArgs e)
{
oc = new ObservableCollection < TestData > ();
oc.Add( new TestData() { d = " A " });
oc.Add( new TestData() { d = " B " });
this .myListBox.ItemsSource = oc;
}
private void btnFind_Click( object sender, RoutedEventArgs e)
{
if (myListBox.SelectedItem != null )
{
ListBoxItem _selectedItem = (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.SelectedItem));
TextBlock myTxt = FindFirstVisualChild < TextBlock > (_selectedItem, " myTxt " );
MessageBox.Show( string .Format( " 选中行的TextBlock值为: " + myTxt.Text));
}
ListBoxItem _firstItem = (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items[ 0 ]));
// var t = _firstItem.FindName("myTxt"); // 这样是找不到的
TextBlock myTxtFirst = FindFirstVisualChild < TextBlock > (_firstItem, " myTxt " );
MessageBox.Show( string .Format( " 第一行的TextBlock值为: " + myTxtFirst.Text));
}
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 ;
}
}
public class TestData{ public string d{ set ; get ;}}
}
这里我们借助VisualTreeHelper对指定行(ListBoxItem)做了一个遍历,以查找符合要求的控件
对于ItemsPanelTemplate中的命名控件,比如下面这样的:
代码
<
ListBox
>
< ItemsPanelTemplate >
< StackPanel Orientation ="Horizontal" x:Name ="sp" ></ StackPanel >
</ ItemsPanelTemplate >
< ListBox.ItemTemplate >
< DataTemplate >
< Rectangle Width ="100" Height ="100" Fill =" {Binding Color} " x:Name ="listItem" MouseLeftButtonDown ="listItem_MouseLeftButtonDown" ></ Rectangle >
</ DataTemplate >
</ ListBox.ItemTemplate >
</ ListBox >
< ItemsPanelTemplate >
< StackPanel Orientation ="Horizontal" x:Name ="sp" ></ StackPanel >
</ ItemsPanelTemplate >
< ListBox.ItemTemplate >
< DataTemplate >
< Rectangle Width ="100" Height ="100" Fill =" {Binding Color} " x:Name ="listItem" MouseLeftButtonDown ="listItem_MouseLeftButtonDown" ></ Rectangle >
</ DataTemplate >
</ ListBox.ItemTemplate >
</ ListBox >
如果想在listItem_MouseLeftButtonDown中引用sp,按正统处理方法还真是比较麻烦(各位可以google,baidu印证),这里给出一个很取巧的办法:
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" x:Name="sp" Loaded="sp_Loaded"></StackPanel>
</ItemsPanelTemplate>
然后在后端代码中,添加一个私有变量,并处理sp_Loaded事件:
StackPanel _sp = null;
private void sp_Loaded(object sender, RoutedEventArgs e)
{
_sp = sender as StackPanel;
}
这样,在listItem_MouseLeftButtonDown中就能借助"_sp"正确引用到ItemsPanelTemplate中的sp了