2008-10-22 82 views
1

我有ListView与分组项目。分组使用自定义GroupStyle(扩展器)。我想有一个复选框,它会在所有组展开和折叠。它工作正常,直到我手动点击组头,并展开或折叠该组。点击特定组后,停止响应复选框选择。用户手动点击该组后,看起来绑定已损坏。ElementName绑定在ControlTemplate中损坏

请告知我做错了什么。

非常感谢。

此致, Vlad。

<Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' 
     xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> 
    <Window.Resources> 
     <XmlDataProvider x:Key="MyData" XPath="/Info"> 
      <x:XData> 
       <Info xmlns=""> 
        <Item Name="Item 1" Category="Cat1" /> 
        <Item Name="Item 2" Category="Cat1" /> 
        <Item Name="Item 3" Category="Cat2" /> 
        <Item Name="Item 4" Category="Cat2" /> 
        <Item Name="Item 5" Category="Cat2" /> 
        <Item Name="Item 6" Category="Cat3" /> 
       </Info> 
      </x:XData> 
     </XmlDataProvider> 

     <CollectionViewSource x:Key='src' Source="{Binding Source={StaticResource MyData}, XPath=Item}"> 
      <CollectionViewSource.GroupDescriptions> 
       <PropertyGroupDescription PropertyName="@Category" /> 
      </CollectionViewSource.GroupDescriptions> 
     </CollectionViewSource> 

     <ControlTemplate x:Key="ListTemplate" TargetType="ListView"> 
      <ListView BorderThickness="0" 
         ItemsSource='{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ItemsSource}' 
         DisplayMemberPath="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisplayMemberPath}"> 
       <ListView.GroupStyle> 
        <GroupStyle> 
         <GroupStyle.ContainerStyle> 
          <Style TargetType="{x:Type GroupItem}"> 
           <Setter Property="Margin" Value="0,0,0,5" /> 
           <Setter Property="Template"> 
            <Setter.Value> 
             <ControlTemplate TargetType="{x:Type GroupItem}"> 
              <Expander IsExpanded="{Binding IsChecked, ElementName=chkExpandAll, Mode=OneWay}"> 
               <Expander.Header> 
                <DockPanel> 
                 <TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100" /> 
                 <TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}" /> 
                </DockPanel> 
               </Expander.Header> 
               <Expander.Content> 
                <ItemsPresenter /> 
               </Expander.Content> 
              </Expander> 
             </ControlTemplate> 
            </Setter.Value> 
           </Setter> 
          </Style> 
         </GroupStyle.ContainerStyle> 
        </GroupStyle> 
       </ListView.GroupStyle> 
      </ListView> 
     </ControlTemplate> 
    </Window.Resources> 

    <StackPanel> 
     <CheckBox Name="chkExpandAll" IsChecked="True" Content="Expand All" /> 
     <ListView ItemsSource='{Binding Source={StaticResource src}}' DisplayMemberPath="@Name" BorderThickness="1" Template="{StaticResource ListTemplate}" /> 
    </StackPanel> 

</Window> 

回答

2

我找到了问题的解决方案。需要做的是指定Mode = TwoWay和UpdateSourceTrigger = Explicit,这样它不会破坏绑定,并且一切正常。贝娄是工作代码的一个例子。

<Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' 
     xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'> 
    <Window.Resources> 
     <XmlDataProvider x:Key="MyData" XPath="/Info"> 
      <x:XData> 
       <Info xmlns=""> 
        <Item Name="Item 1" Category="Cat1" /> 
        <Item Name="Item 2" Category="Cat1" /> 
        <Item Name="Item 3" Category="Cat2" /> 
        <Item Name="Item 4" Category="Cat2" /> 
        <Item Name="Item 5" Category="Cat2" /> 
        <Item Name="Item 6" Category="Cat3" /> 
       </Info> 
      </x:XData> 
     </XmlDataProvider> 

     <CollectionViewSource x:Key='src' Source="{Binding Source={StaticResource MyData}, XPath=Item}"> 
      <CollectionViewSource.GroupDescriptions> 
       <PropertyGroupDescription PropertyName="@Category" /> 
      </CollectionViewSource.GroupDescriptions> 
     </CollectionViewSource> 

     <ControlTemplate x:Key="ListTemplate" TargetType="ListView"> 
      <ListView BorderThickness="0" 
         ItemsSource='{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ItemsSource}' 
         DisplayMemberPath="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisplayMemberPath}"> 
       <ListView.GroupStyle> 
        <GroupStyle> 
         <GroupStyle.ContainerStyle> 
          <Style TargetType="{x:Type GroupItem}"> 
           <Setter Property="Margin" Value="0,0,0,5" /> 
           <Setter Property="Template"> 
            <Setter.Value> 
             <ControlTemplate TargetType="{x:Type GroupItem}"> 
              <StackPanel> 
              <Expander Name="exp" IsExpanded="{Binding IsChecked, ElementName=chkExpandAll, Mode=TwoWay, UpdateSourceTrigger=Explicit}"> 
               <Expander.Header> 
                <DockPanel> 
                 <TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100" /> 
                 <TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}" /> 
                </DockPanel> 
               </Expander.Header> 
               <Expander.Content> 
                <ItemsPresenter /> 
               </Expander.Content> 
              </Expander> 
              </StackPanel> 
             </ControlTemplate> 
            </Setter.Value> 
           </Setter> 
          </Style> 
         </GroupStyle.ContainerStyle> 
        </GroupStyle> 
       </ListView.GroupStyle> 
      </ListView> 
     </ControlTemplate> 
    </Window.Resources> 

    <StackPanel> 
     <CheckBox Name="chkExpandAll" Content="Expand All" /> 
     <ListView ItemsSource='{Binding Source={StaticResource src}}' DisplayMemberPath="@Name" BorderThickness="1" Template="{StaticResource ListTemplate}" /> 
    </StackPanel> 

</Window> 
+0

此替代方法似乎对我无效。 – jpierson 2011-06-27 17:20:24

0

它看起来像,因为它被设置为单向的与复选框被打破的结合,然后如果你点击任何的扩展那么它会打破约束力。将它设置为TwoWay将使它始终工作,但扩展一个项目将导致它们全部展开,这不是很有用。

我相信这样做的解决方案是不使用绑定,而是使用情节提要。无论当前状态如何,您都可以触发故事板,这会导致所有扩展器设置为true/false。更新复选框可能会更棘手,因为有一些逻辑需要查看是否所有复选框或只有一些复选框被选中。

+0

感谢您的回复,你有没有通过故事板做到这一点的例子?你可以使用我的例子,它在XAMLPad和KAXAML中工作,只需复制和粘贴即可。我也不明白更新复选框。顶部只有一个复选框,它应该展开所有扩展器或全部折叠它们。我不认为我需要担心如何更新它。再次感谢。此致, 弗拉德。 – 2008-10-22 22:44:16