WP8 ListBox中的FindAncestor实现 [英] FindAncestor implementation in WP8 ListBox

查看:89
本文介绍了WP8 ListBox中的FindAncestor实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想直接实现Listbox绑定,这是我在WPF语法中使用的代码

I want to implement a Listbox binding directly and here is the code i used in WPF syntax

<ListBox  Name="lboxData" ItemsSource="{Binding}">
<ListBox.ItemTemplate >
    <DataTemplate>
        <StackPanel>                        
            <ToggleButton x:Name="toggleChild"  Style="{StaticResource ChapterHeadingStyle}"
                  IsChecked="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}"   // This is what i have to change . I want to set it based on the status of the ListBoxItem & Given code is the one i used in WPF app 
            />
            <ListBox Visibility="{Binding IsChecked, ElementName=toggleChild, Converter={StaticResource boolToVis}}" ItemsSource="{Binding pages}" Margin="10,0,0,0"  >
                        <ListBox.ItemTemplate >
                            <DataTemplate>
                              //here is displaying child items one by one ..
                            </DataTemplate>
                        </ListBox.ItemTemplate >
            </ListBox>
         </ListBox.ItemTemplate >
    </DataTemplate>
</StackPanel>       
</ListBox>

问题在于,在WP8中, RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = {x:Type ListBoxItem} 不受支持.因此,我如何在WP8中实现相同的目的.如果要将容器ListboxItem选中,我想将切换按钮设置为已检查",否则我要将IsChecked设置为False.

The problem is that in WP8 RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem} is not supported . So how can i achieve the same thing in WP8. I want to set the toggle button as Checked if the container ListboxItem is selected , else i want to set the IsChecked as False.

推荐答案

我将首先编写一个比较器类

I'll start by writing a comparer class

public  class ElementComparer : FrameworkElement
{
    public object Element1
    {
        get { return (object)GetValue(Element1Property); }
        set { SetValue(Element1Property, value); }
    }

    // Using a DependencyProperty as the backing store for Element1.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty Element1Property =
        DependencyProperty.Register("Element1", typeof(object), typeof(ElementComparer), new PropertyMetadata(null, UpdateResult));

    public object Element2
    {
        get { return (object)GetValue(Element2Property); }
        set { SetValue(Element2Property, value); }
    }

    // Using a DependencyProperty as the backing store for Element2.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty Element2Property =
        DependencyProperty.Register("Element2", typeof(object), typeof(ElementComparer), new PropertyMetadata(null, UpdateResult));

    public bool Result
    {
        get { return (bool)GetValue(ResultProperty); }
        set { SetValue(ResultProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Result.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ResultProperty =
        DependencyProperty.Register("Result", typeof(bool), typeof(ElementComparer), new PropertyMetadata(false, OnResultChanged)); //added changed handler

    private static void OnResultChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ElementComparer ec = d as ElementComparer;
        //if true then set the element 2 to element 1 of the comparer otherwise null
        ec.Element2 = ((bool)e.NewValue) ? ec.Element1 : null;
    }

    private static void UpdateResult(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ElementComparer ec = d as ElementComparer;
        ec.Result = object.ReferenceEquals(ec.Element1, ec.Element2);
    }
}

然后我将IsChecked从切换按钮绑定到ElementComparer的结果,并将comaprer的Element1和Element2与当前项和lboxData(ListBox)的SelectedItem绑定

then I'll bind IsChecked from togglebutton to the Result of ElementComparer and will bind the Element1 and Element2 of the comaprer with the current item and the SelectedItem of lboxData (ListBox)

<ListBox Name="lboxData" ItemsSource="{Binding}">
    <ListBox.ItemTemplate >
        <DataTemplate>
            <StackPanel>
                <!--added  Mode=TwoWay to binding of Element2-->
                <local:ElementComparer x:Name="ElementComparer"
                                    Element1="{Binding}"
                                    Element2="{Binding SelectedItem, ElementName=bookTOCBox, Mode=TwoWay}" />
                <!--removed Mode=OneWay from binding of IsChecked and added Mode=TwoWay-->
                <ToggleButton x:Name="toggleChild" Content="{Binding name}" 
                              Style="{StaticResource ChapterHeadingStyle}" 
                              IsChecked="{Binding Result, ElementName=ElementComparer, Mode=TwoWay}"/>
                ...
            </StackPanel>

诀窍是,只要父列表框的名称为"lboxData",就可以将列表中的所选项目与当前项目进行比较,以检测是否选中了该项目,这在WP8中也可以使用

the trick is to compare the selected item of the list to the current item to detect if it is selected as long as the name of parent listbox is "lboxData", this will work in WP8 too

更新摘要

  • 从切换的IsChecked属性到ElementComparer的结果中删除了一种方法绑定
  • 将与SelectedItem的双向绑定添加到ElementComparer的Element2中
  • 为ElementComparer中的Result属性添加了属性更改处理程序
  • 当结果更改且为true(已选中切换)时,将Element1的值推入Element2
  • 由于Element2绑定到SelectedItem,因此它会强制其他项的结果为false,因此请关闭切换开关并折叠子列表
  • 添加的Mode = Trigger的IsChecked双向属性,如果没有它,似乎退出是无法预测的

其他

此外,如果您不想在列表项中看到难看的蓝色选择,那么也可以在资源中添加以下内容

additionally if you don't want to see ugly looking blue selection in list items then you may add the following to your resources too

<Style TargetType="ListBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Border Background="Transparent">
                    <ContentPresenter/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这篇关于WP8 ListBox中的FindAncestor实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆