2014-01-20 7 views
1

Мое мнение работает так. У меня есть Observable Collection, которая содержит объекты, помещенные в список. Нажимая на любой элемент, я могу открыть расширитель, связанный с этим элементом. Вот вопрос: Как я могу свернуть (закрыть) ранее открытый расширитель при открытии другого? Я не хочу иметь ситуацию, когда одновременно открываются несколько расширителей.Свернуть раскрывающиеся расширители в `Datatemplate`, когда мы открываем новый

Моего WPF код выглядит следующим образом:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 
     <controls:Pivot> 
      <controls:PivotItem> 
       <ListBox x:Name="PizzaList" SelectionChanged="PizzaList_SelectionChanged" IsSynchronizedWithCurrentItem="false" > 
        <ListBox.ItemTemplate> 
         <DataTemplate x:Name="template"> 

          <toolkit:ExpanderView Header="{Binding Name}" x:Name="expander" Style="{StaticResource ExpanderViewStyle}"> 
           <toolkit:ExpanderView.Items> 
            <!--first stack panel would contain all elements which would be showed 
            after clicking on listbox item--> 
            <StackPanel Margin="20,0,0,0" Orientation="Vertical"> 
        <!-- here is content of expander-->      
            </StackPanel> 
           </toolkit:ExpanderView.Items> 
           <toolkit:ExpanderView.Expander> 
            <TextBlock Text="{Binding Name_of_ingredients}" Width="500"></TextBlock> 
           </toolkit:ExpanderView.Expander> 
          </toolkit:ExpanderView> 


         </DataTemplate> 
        </ListBox.ItemTemplate> 
       </ListBox> 
      </controls:PivotItem> 
     </controls:Pivot> 
    </Grid> 

Я мог бы иметь статическое количество расширителей, если бы я работал с фиксированным набором данными, но когда расширитель находится в шаблоне данных, количество элементов может изменение. Я не знаю, как это решить.

ответ

2

Я думаю, что это может помочь:

private void PizzaListSelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    foreach (var item in PizzaList.Items) 
    { 
     var listBoxItem = 
      PizzaList.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem; 
     var itemExpander = (Expander) GetExpander(listBoxItem); 
     if (itemExpander != null) 
      itemExpander.IsExpanded = false; 
    } 
} 

и поиск Expander

private static DependencyObject GetExpander(DependencyObject container) 
{ 
    if (container is Expander) return container; 

    for (var i = 0; i < VisualTreeHelper.GetChildrenCount(container); i++) 
    { 
     var child = VisualTreeHelper.GetChild(container, i); 

     var result = GetExpander(child); 
     if (result != null) 
     { 
      return result; 
     } 
    } 

    return null; 
} 

Больше способов найти элементы управления в этом вопросе How can I find WPF controls by name or type?

+0

работает так хорошо, ТНХ много – MyWay

0

Я надеюсь, что это выглядит нормально, убежище» t отправил код раньше.

Я нашел это решение для расширения/свертывания listboxitems. Ниже приведена сетка, содержащая мой контент. Его высота представляет собой фактическую высоту содержимого внутри панели стека (x: Name = "stack") и сохраняется в свойстве тега Grid. DataTrigger оживляет тег. Обычай: XSButton происходит от CustomControls от Andy L и действует как ToggleButton. Просто нужен этот конвертер для высоты сетки.

public class MultiplyConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     double result = 1.0; 
     for (int i = 0; i < values.Length; i++) 
     { 
      if (values[i] is double) 
       result *= (double)values[i]; 
     } 

     return result; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new Exception("Not implemented"); 
    } 
} 

Сетка

   <Grid x:Name="Grid" Grid.ColumnSpan="3" Grid.Row="1" > 
        <Grid.Tag> 
         <System:Double>0.0</System:Double> 
        </Grid.Tag> 
        <Grid.Height> 
         <MultiBinding Converter="{StaticResource multiplyConverter}"> 
          <Binding Path="ActualHeight" ElementName="stack"/> 
          <Binding Path="Tag" RelativeSource="{RelativeSource Self}" /> 
         </MultiBinding> 
        </Grid.Height> 
        <custom:XSButton IsChecked="{Binding 
         RelativeSource={RelativeSource FindAncestor, 
         AncestorType={x:Type ListBoxItem}}, 
         Path=IsSelected}" Background="Transparent" BorderThickness="0" BorderBrush="Transparent" 
             ClickMode="Press" 
            Foreground="Transparent" Style="{DynamicResource XSButtonStyle1}" > 
        <StackPanel x:Name="stack"> 
         <TextBlock Text="{Binding Text}" FontSize="13.333" TextWrapping="Wrap" Foreground="#FFC0C7C8"/> 
         <TextBlock Text="{Binding Status_Message}" FontSize="13.333" TextWrapping="Wrap" Foreground="#FFC0C7C8"/> 
         </StackPanel> 
        </custom:XSButton> 
       </Grid> 

DataTrigger для расширения/разрушения

 <DataTemplate.Triggers> 
      <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True"> 

       <DataTrigger.EnterActions> 
        <BeginStoryboard> 
         <Storyboard> 
          <DoubleAnimation Storyboard.TargetName="Grid" Storyboard.TargetProperty="Tag" To="1" Duration="0:0:0.4"/> 
         </Storyboard> 
        </BeginStoryboard> 
       </DataTrigger.EnterActions> 
       <DataTrigger.ExitActions> 
        <BeginStoryboard> 
         <Storyboard> 
          <DoubleAnimation Storyboard.TargetName="Grid" Storyboard.TargetProperty="Tag" To="0" Duration="0:0:0.4"/> 
         </Storyboard> 
        </BeginStoryboard> 
       </DataTrigger.ExitActions> 
      </DataTrigger> 

     </DataTemplate.Triggers> 

 Смежные вопросы

  • Нет связанных вопросов^_^