Несколько Expander должны разрушиться, если ОДИН расширен - PullRequest
11 голосов
/ 15 декабря 2010

Наличие 4 элементов управления Expander. Когда один расширитель развернут, как я могу сделать так, чтобы все остальные развернулись / закрылись?

Ответы [ 7 ]

29 голосов
/ 15 декабря 2010

Попробуйте следующий код:

XAML:

        <StackPanel Name="StackPanel1">
            <StackPanel.Resources>
                <local:ExpanderToBooleanConverter x:Key="ExpanderToBooleanConverter" />
            </StackPanel.Resources>
            <Expander Header="Expander 1"
                      IsExpanded="{Binding SelectedExpander, Mode=TwoWay, Converter={StaticResource ExpanderToBooleanConverter}, ConverterParameter=1}">
                <TextBlock>Expander 1</TextBlock>
            </Expander>
            <Expander Header="Expander 2"
                      IsExpanded="{Binding SelectedExpander, Mode=TwoWay, Converter={StaticResource ExpanderToBooleanConverter}, ConverterParameter=2}">
                <TextBlock>Expander 2</TextBlock>
            </Expander>
            <Expander Header="Expander 3"
                      IsExpanded="{Binding SelectedExpander, Mode=TwoWay, Converter={StaticResource ExpanderToBooleanConverter}, ConverterParameter=3}">
                <TextBlock>Expander 3</TextBlock>
            </Expander>
            <Expander Header="Expander 4"
                      IsExpanded="{Binding SelectedExpander, Mode=TwoWay, Converter={StaticResource ExpanderToBooleanConverter}, ConverterParameter=4}">
                <TextBlock>Expander 4</TextBlock>
            </Expander>
        </StackPanel>

Преобразователь:

public class ExpanderToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value == parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (System.Convert.ToBoolean(value)) return parameter;
        return null;
    }
}

ViewModel:

public class ExpanderListViewModel
{
    public Object SelectedExpander { get; set; }
}

1012 * инициализация * StackPanel1.DataContext = new ExpanderListViewModel(); Пояснение: В XAML у нас есть 4 расширителя. Все они наследуют ViewModel (типа ExpanderListViewModel) из контейнера с StackPanel по DataContext. Все они связаны с одним свойством в ViewModel классе. И определили уникальный индекс для себя, используя ConverterParameter в привязке. Этот индекс сохраняется в свойстве SelectedExpander всякий раз, когда вы расширяете расширитель. И используя этот индекс, Converter возвращает true, если сохраненный индекс соответствует данному индексу, и false, если сохраненный индекс не совпадает. Поставьте точку останова в Convert и ConvertBack методах класса Converter, и вы увидите, что происходит.

3 голосов
/ 14 октября 2011

Просто установить потерянный фокус, кажется, самый простой способ сделать это.

Xaml:

<Expander LostFocus="CollapseExpander" ExpandDirection="Down" Width="175">
    <ListBox Height="265" Margin="0,5,0,10">
    </ListBox>
</Expander>

VB:

Private Sub CollapseExpander(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

 sender.IsExpanded = False

End Sub
2 голосов
/ 14 февраля 2015

вот как я это сделал:

1) добавил StackPanel и ДОЛЖЕН добавить атрибут тега name (так как это мастер).

StackPanel Name = "StackPanel1«

2) добавьте столько расширителей, сколько вам нужно (от 1 до 100 при необходимости), каждый из них ДОЛЖЕН иметь: -

Expanded =« Expander_Expanded »

добавлено (обратите внимание, что все они имеют одинаковую формулировку на 100%).

3) никакие другие детали не должны совпадать с каждым (без имен высот и т. Д.).

Xaml:

<StackPanel Name="StackPanel1">
<Expander Header="Expander 1" Expanded="Expander_Expanded">
    <TextBlock>Expander 1</TextBlock>
</Expander>
<Expander Header="Expander 2" Expanded="Expander_Expanded">
    <TextBlock>Expander 2</TextBlock>
</Expander>
<Expander Header="Expander 3" Expanded="Expander_Expanded" >
    <TextBlock>Expander 3</TextBlock>
</Expander>
<Expander Header="Expander 4" Expanded="Expander_Expanded" >
    <TextBlock>Expander 4</TextBlock>
</Expander>

4) Для управления открытием / закрытием всех «Расширителей» на названной StackPanel1 «StackPanel» вам нужно добавить приведенный ниже код только один раз.

Код VB:

Private Sub Expander_Expanded(sender As Object, e As RoutedEventArgs)
    For Each exp As Expander In StackPanel1.Children
        If exp IsNot sender Then
            exp.IsExpanded = False
        End If
    Next
End Sub

5) Теперь вы можете изменять / добавлять контент, кнопки, текстовые поля и т. Д., Которые вам просто не нужно менять, 2 вещи 1, «Имя StackPanel» 2, «Расширитель»Расширено "без обновления кода, иначе все не будет работать.

Надеюсь, эта информация вам пригодится.

Что происходит?

1) All панели являются родителями, и все элементы управления на этой панели являются дочерними,

2) Все элементы управления являются дочерними элементами родительской панели.

3) Класс обрабатывает один вызов за раз.

4) Класс занимается с ребенком.

6) Класс переходит к следующему ребенку.

7) Останавливается, когда всех детей спрашивают.

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

1) Прослушайте ребенка по имени x

2) Спросите каждого ребенка в списке родителей родителей

3) Если ребенок не звонитзатем

4) Расширение ребенка ложно

5) Прекратите спрашивать этого ребенка

6) Перейдите к следующему ребенку и спросите снова

7) Довсех детей спросили

1 голос
/ 20 июля 2016

@ wassim-azirar спросил на принятый ответ:

Как мне развернуть 'Expander 1' при запуске приложения?

Я добавил в ViewModel:

SelectedExpander = "1";

Из-за того факта, что «1» не является тем же объектом, что и «1» в XAML, это не сработает, поэтому я изменил ответ дециклона так:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    return (string)value == (string)parameter;
}

Ответ дециклона был очень полезен для меня - спасибо.
Так что я хотел бы поделиться своим опытом, если кому-то это нужно.

1 голос
/ 15 декабря 2010

Используйте MVVM и привяжите свойство IsExpanded к логическому флагу на ваших моделях представления.Когда один из них обновляется до true, установите для всех остальных значение false.

0 голосов
/ 06 октября 2014

Мне тоже это нужно было, но для всех ответов было слишком много работы IMO. Вот как я это сделал:

  1. добавлен StackPanel (дочернее выравнивание установлено по вертикали).
  2. добавил 3 Расширителя в него. (нужно 3)
  3. установите высоту Expanders равной 120px, чтобы добавить к ней элементы.
  4. каждый расширитель называется ex1..3.
  5. каждый получил 2 события

    private void ex1_Collapsed(object sender, RoutedEventArgs e)  
    {  
        ex1.Height = 23.0;  
    }  
    
    private void ex1_Expanded(object sender, RoutedEventArgs e)    
    {  
        ex1.Height = 120.0;  
        ex2.IsExpanded = false;  
        ex3.IsExpanded = false;  
    }  
    
  6. сбросить все расширители, высота которых должна быть свернута, до 23px при загрузке окна.

что это.

0 голосов
/ 15 декабря 2010

Попробуйте элемент управления Accordion из WPF Toolkit - выпуск за февраль 2010 г.

http://www.dotnetspark.com/kb/1931-accordion-wpf-toolkit-tutorial.aspx

Пример кода:

<my:Accordion  x:Name="accordion1" VerticalAlignment="Top" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" SelectionMode="ZeroOrOne">
        <my:AccordionItem Header="First Header" Content="First Content"/>
        <my:AccordionItem Header="Second Header">
            <StackPanel Height="300">
            <TextBlock Text="Second Content" /></StackPanel>
        </my:AccordionItem>
        <my:AccordionItem>
            <my:AccordionItem.Header>
                <TextBox Text="Third Item" />
            </my:AccordionItem.Header>
            <StackPanel Height="300">
                <TextBlock Text="Third Item" />
            </StackPanel>
        </my:AccordionItem>
        <my:AccordionItem>
            <my:AccordionItem.Header>
                <TextBlock Text="Fourth Item" />
            </my:AccordionItem.Header>
            <StackPanel Height="300">
                <TextBlock Text="Third Item" />
            </StackPanel>
        </my:AccordionItem>
    </my:Accordion>
...