none
ListBox如何设置DataTemplate名称供代码中访问? RRS feed

  • 问题

  • 场景:想绑定数据到ListBox,子元素为CheckBox,最终遍历所有元素获取IsChecked状态进行后期数据处理。

    代码如下:

    <ListBox Name="lsbLabel">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Path=LabelName}" Height="16" Tag="{Binding Path=LabelId}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    在网上搜索了一下一般处理方式:几乎都是给DataTemplate起个名字(x:Key或x:Name),然后在代码中访问这个变量借助VisualTreeHelper进行操作。整个过程还是比较清晰,但是我实际操作时问题来了。

    DataTemplate用x:Name命名后,代码中无法找到这个变量。所以之后的操作都没有办法实现。在MSDN的文章How to: Find DataTemplate-Generated Elements(http://msdn.microsoft.com/en-us/library/bb613579.aspx)中,对DataTemplate命名是采用的x:Key,但是这里x中只有Name、FieldModifier、Uid供选择……这是个什么情况?应该怎样命名才能在代码中获取到该DataTemplate对象?

    谢谢。


    QQ: 79965521 Email: WolfLai@126.com

    2012年11月1日 15:36

答案

  • 这个一般是从数据源去查看IsChecked属性的值的。

    如果你非要遍历,你可以这样遍历ListBox里面所有的CheckBox:

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }
    
                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }
    foreach (CheckBox cb in FindVisualChildren<CheckBOx>(ListBox))
    {
        // do something with tb here
    }


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Wolf Lai 2012年11月7日 14:20
    2012年11月6日 7:45
    版主

全部回复

  • 仔细阅读并测试以上提及的文章中的例子。我想我知道应该怎么做遍历了:稍微改一下例子中的代码,由遍历项代替CurrentItem就行了。

    foreach(var item in myListBox.Items)
    {
    ListBoxItem myListBoxItem =
        (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(item));
    
    ...
    }

    但是,还是有一个问题:不能在xaml中对DataTemplate命名,然后在代码中使用?


    QQ: 79965521 Email: WolfLai@126.com


    • 已编辑 Wolf Lai 2012年11月1日 17:02
    2012年11月1日 16:21
  • 1.DataTemplate 在xaml中保存为资源 ,并用x:Key提供一个名字

    在代码中使用的时候可以使用FindResource(keyname) 来取得这个资源。

    2.想绑定数据到ListBox,子元素为CheckBox,最终遍历所有元素获取IsChecked状态进行后期数据处理。--〉

    后台的数据item最好绑定义一个bool属性绑定到checkbox的Ischecked,这样就可以不要去遍历界面了。

    2012年11月2日 13:58
  • 你不应该关心DataTemplate的东西, 那是view的事情.

    你关心了说明你的设计有问题.

    2012年11月5日 12:31
  • 这个一般是从数据源去查看IsChecked属性的值的。

    如果你非要遍历,你可以这样遍历ListBox里面所有的CheckBox:

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }
    
                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }
    foreach (CheckBox cb in FindVisualChildren<CheckBOx>(ListBox))
    {
        // do something with tb here
    }


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 Wolf Lai 2012年11月7日 14:20
    2012年11月6日 7:45
    版主
  • 受教了,谢谢。

    QQ: 79965521 Email: WolfLai@126.com

    2012年11月7日 14:22