Windows phone 8 WP8列表框中的FindAncestor实现

Windows phone 8 WP8列表框中的FindAncestor实现,windows-phone-8,listbox,findancestor,Windows Phone 8,Listbox,Findancestor,我想直接实现Listbox绑定,下面是我在WPF语法中使用的代码 <ListBox Name="lboxData" ItemsSource="{Binding}"> <ListBox.ItemTemplate > <DataTemplate> <StackPanel> <ToggleButton x:Name="toggleChild" Sty

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

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

//下面将逐个显示子项。。

问题在于,在WP8RelativeSource={RelativeSource Mode=FindAncestor中,AncestorType={x:Type ListBoxItem}不受支持。因此如何在WP8中实现同样的效果。如果选择了容器ListboxItem,我想将切换按钮设置为选中,否则我想将IsChecked设置为False。

我将从编写比较器类开始

公共类元素比较器:FrameworkElement
{
公共对象元素1
{
获取{return(object)GetValue(Element1Property);}
set{SetValue(Element1Property,value);}
}
//使用DependencyProperty作为Element1的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性元素1属性=
Register(“Element1”、typeof(object)、typeof(ElementComparer)、newpropertyMetadata(null、UpdateResult));
公共对象元素2
{
获取{return(object)GetValue(Element2Property);}
set{SetValue(Element2Property,value);}
}
//使用DependencyProperty作为Element2的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性Element2Property=
Register(“Element2”,typeof(object),typeof(ElementComparer),newpropertyMetadata(null,UpdateResult));
公共布尔结果
{
获取{return(bool)GetValue(ResultProperty);}
set{SetValue(ResultProperty,value);}
}
//使用DependencyProperty作为结果的后备存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性ResultProperty=
Register(“Result”、typeof(bool)、typeof(ElementComparer)、newpropertyMetadata(false、OnResultChanged));//添加了已更改的处理程序
私有静态void OnResultChanged(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
ElementComparer ec=d作为ElementComparer;
//如果为true,则将比较器的元素2设置为元素1,否则为null
ec.Element2=((bool)e.NewValue)?ec.Element1:null;
}
私有静态void UpdateResult(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
ElementComparer ec=d作为ElementComparer;
ec.Result=object.ReferenceEquals(ec.Element1,ec.Element2);
}
}
然后我将IsChecked from togglebutton绑定到ElementComparer的结果,并将Comaper的Element1和Element2与当前项和lboxData的SelectedItem绑定(列表框)


...
诀窍是将列表中的选定项与当前项进行比较,以检测是否选中了该项,只要父列表框的名称为“lboxData”,这在WP8中也会起作用

更新摘要

  • 已删除从toggle的IsChecked属性到ElementComparer结果的单向绑定
  • 添加了双向绑定,将SelectedItem绑定到ElementComparer的Element2
  • 在ElementComparer中为结果属性添加了属性更改处理程序
  • 当结果更改且为真时(选中切换),将Element1的值推送到Element2
  • 由于Element2绑定到SelectedItem,因此它会强制其他项的结果为false,因此关闭切换并折叠子列表
  • 添加Mode=TwoWay以检查toggle的属性,因为如果没有它,似乎无法预测
附加服务

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



我尝试了这些示例,但在2点1处出现异常。多重绑定不是有效的xaml标记,并且缺少IMultiValueConverter命名空间。我如何覆盖这两个问题?对以前的方法表示歉意,因为我不知道多重绑定和转换器被排除在metro应用程序之外。我修改了我的解决方案,使其在没有它的情况下工作这更有可能对WP8起作用。是的,已经起作用了。但还没有完全起作用,我正在努力按照我想要的方式完成。我将很快上传详细的问题描述。我期望列表框的行为方式-首先,在选择项目(比如列表中的第一个项目)后,所有主要项目都会折叠(未选中),基础项应展开。选择另一项后(如列表中的第三项),所有其他选定项应折叠,新项(即第三个项)应展开。但现在的行为更像是,起初所有项均未选定。我选择项1,它展开了它的所有子项。我选择项3,现在项1和3都处于展开状态。此处使用的xaml结构,切换按钮需要模式=双向n也是