如果扩展一个扩展器,则多个扩展器必须折叠

发布于 2024-10-08 01:39:55 字数 53 浏览 7 评论 0原文

我有 4 个扩展器控件。

当一个扩展器扩展时,如何使所有其他扩展器折叠/关闭?

I have 4 expander controls.

When one expander is expanded, how can I make all others collapse/close?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

ヤ经典坏疍 2024-10-15 01:39:55

尝试以下代码:

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>

Converter:

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

Initialization

StackPanel1.DataContext = new ExpanderListViewModel();

说明:

在 XAML 中,我们有 4 个扩展器。它们都从容器 StackPanel 通过 DataContext 继承了 ViewModel(类型为 ExpanderListViewModel)。

它们都绑定到 ViewModel 类上的单个属性。并在绑定中使用 ConverterParameter 为自己定义了唯一索引。每当您展开扩展器时,该索引都会保存在 SelectedExpander 属性中。使用该索引,如果存储的索引与给定索引匹配,则 Converter 返回 true;如果存储的索引不匹配,则返回 false

Converter 类的 ConvertConvertBack 方法中放置断点,您将看到发生了什么。

Try out following code:

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>

Converter:

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

Initialization

StackPanel1.DataContext = new ExpanderListViewModel();

Explanation:

In XAML we have 4 expanders. They all inherit a ViewModel (of type ExpanderListViewModel) from container StackPanel through DataContext.

They all bind to single property on ViewModel class. And have defined a unique index for themselves using ConverterParameter in binding. That index gets saved in SelectedExpander property whenever you expand an expander. And using that index, the Converter returns true if the stored index matches with given index and false if stored index does not match.

Put a breakpoint in Convert and ConvertBack methods of Converter class and you will see what is going on.

青芜 2024-10-15 01:39:55

我就是这样做的:

1)添加了一个 StackPanel 并且必须添加一个名称标签属性(因为这是主面板)。

StackPanel名称=“StackPanel1”

2) 根据需要添加任意数量的扩展器(如果需要,可添加 1 到 100 个),每个扩展器必须具有:-

扩展=“Expander_Expanded”

(注意所有措辞 100% 相同)。

3)没有其他细节需要匹配(不需要身高的名字等)。

XML:

<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 上所有“Expander”的打开/关闭,您只需添加以下代码一次。

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、“Expander Expanded”,而无需更新其他代码隐藏内容不会起作用。

希望这些信息对您有帮助。

发生什么事了?

1) 所有面板都是父面板,该面板上的所有控件都是子面板,

2) 所有控件都是父面板的子面板。

3) 一个类一次处理一个调用。

4)班级与孩子打交道。

6) 班级移至下一个孩子。

7) 一旦所有孩子都被问到,就停止。

所以伪代码是这样的:

1) 监听一个孩子的名字 x

2) 询问孩子父母列表中的每个孩子

3) 如果孩子没有打电话,那么

4) 孩子展开是假的

5) 结束询问孩子

6) 移动到下一个孩子并再次询问

7) 直到所有孩子都被问过

this is how I did it:

1) added a StackPanel and MUST add a name tag attribute (as this is the master).

StackPanel Name="StackPanel1"

2) add as many Expanders as you need (1 to 100's if needed) each MUST have:-

Expanded="Expander_Expanded"

added (notice all have 100% the same wording).

3) no other details need to match on each ( no height's names etc.. needed).

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) To control the open/close of all "Expanders" on the named "StackPanel1" StackPanel you only need to add the below code once.

VB code-behind:

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)Now you can change/add what content, button's, textbox's etc.. you need just do not change 2 things 1, "StackPanel Name" 2, "Expander Expanded" without updating the code-behind else things will not work.

Hope this information is helpful to you.

What's happening?

1) All panels are parents and all controls on that panel are children,

2) All controls are children of a parent panel.

3) A class deals with one call at a time.

4) The class deals with child.

6) The class move to next child.

7) Stops once all children have been asked.

So the pseudo code is like this:

1) Listen for a child’s named x

2) Ask each child in parents list of children

3) If child is not calling then

4) Child is expanded is false

5) End asking that child

6) Move to next child and ask again

7) Until all children have been asked

仲春光 2024-10-15 01:39:55

只需设置“失去焦点”似乎是最简单的方法。

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

Just setting the Lost focus seems to be the easiest way to do this.

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
过期情话 2024-10-15 01:39:55

使用 MVVM 并将 IsExpanded 属性绑定到视图模型上的布尔标志。当其中一个更新为 true 时,将所有其他设置为 false

Use MVVM and bind the IsExpanded property to a boolean flag on your view models. When one is updated to true, set all the others to false.

挽手叙旧 2024-10-15 01:39:55

@wassim-azirar 询问已接受的答案:

如何在应用程序启动时扩展“Expander 1”?

我在 ViewModel 中添加:

SelectedExpander = "1";

因为事实上,“1”与 XAML 中的“1”不是同一个对象,所以这是行不通的,所以我改变了 decyclone 的答案,如下所示:

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

decyclone 的答案对我来说非常有帮助- 谢谢。
所以我想分享一下我的经验,如果有人需要的话。

@wassim-azirar asked to the accepted answer:

How can I expand 'Expander 1' at the application Startup ?

I added in the ViewModel:

SelectedExpander = "1";

Because of the fact, that the "1" is not the same object as the "1" in XAML this will not work, so I changed decyclone's answer like this:

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

The answer of decyclone was very helpful for me - Thanks.
So I would like to share my experience if someone needs it.

遥远的绿洲 2024-10-15 01:39:55

尝试 WPF 工具包 - 2010 年 2 月发布

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>

Try the Accordion control from WPF Toolkit - February 2010 Release

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

Sample code:

<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>
上课铃就是安魂曲 2024-10-15 01:39:55

我也需要这个,但在我看来,所有答案都太费力了。
我是这样做的:

  1. 添加了 StackPanel(子对齐设置为垂直)。
  2. 添加了 3 个扩展器。 (需要 3)
  3. 将 Expanders 的高度设置为 120px 以向其添加元素。
  4. 每个扩展器称为 ex1..3。
  5. 每人有 2 个事件

    private void ex1_Collapsed(对象发送者, RoutedEventArgs e)  
    {  
        ex1.高度 = 23.0;  
    }  
    
    私人无效 ex1_Expanded(对象发送者, RoutedEventArgs e)    
    {  
        ex1.高度 = 120.0;  
        ex2.IsExpanded = false;  
        ex3.IsExpanded = false;  
    }  
    
  6. 将所有应该折叠高度的 Expander 重置回 window_loaded 时的 23px。

那个它。

I also needed this, but all answers was too much work IMO.
Here is how I did it:

  1. added StackPanel (child align is set to vertical).
  2. added 3 Expanders into it. (needed 3)
  3. set height of Expanders to 120px to add elements to it.
  4. each Expander called ex1..3.
  5. each one got 2 events

    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. reset all the Expanders that should be collapsed height back to 23px at window_loaded.

that it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文