您的位置:首页 > 移动开发 > Objective-C

WP7 ListBox中如何取得DateTemplate/ItemsPanelTemplate中的命名控件?

2012-04-17 18:32 531 查看



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>

复制代码

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;}}

}

这里我们借助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>

如果想在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了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  null object google class
相关文章推荐