WPF - 如何在任一时间仅扩展一个扩展器

发布于 2024-08-14 16:49:09 字数 73 浏览 8 评论 0原文

我有一个带有一组扩展器的 StackPanel,如何设置它以便在任何时候都只扩展扩展器?

干杯

AW

I've got a StackPanel with a group of expanders in, how do I set it so that only expander is expanded at any one time?

Cheers

AW

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

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

发布评论

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

评论(4

§普罗旺斯的薰衣草 2024-08-21 16:49:09

我真的不想这样做,因为它需要将代码(C#)放在窗口文件后面的类中(我试图通过使用 ViewModels 等来完全避免这种情况)。

理想情况下,我会在 XAML 中对此进行描述。

我连接了我感兴趣的每个 Expander“Expanded”活动并执行了以下操作:

    private void HandleExpanderExpanded(object sender, RoutedEventArgs e)
    {
        ExpandExculsively(sender as Expander);
    }

    private void ExpandExculsively(Expander expander)
    {
        foreach (var child in findPanel.Children)
        {
            if (child is Expander && child != expander)
                ((Expander)child).IsExpanded = false;
        }
    }

Cheers

AWC

I didn't really want to do it like this as it required putting code (C#) in the class behind file for the window (I'm trying to avoid this completely by use of ViewModels etc).

Ideally I would have described this in XAML.

I hooked up every Expander 'Expanded' event I was interested in and did the following:

    private void HandleExpanderExpanded(object sender, RoutedEventArgs e)
    {
        ExpandExculsively(sender as Expander);
    }

    private void ExpandExculsively(Expander expander)
    {
        foreach (var child in findPanel.Children)
        {
            if (child is Expander && child != expander)
                ((Expander)child).IsExpanded = false;
        }
    }

Cheers

AWC

瑶笙 2024-08-21 16:49:09

用户“Dabblernl”将此作为评论发布,但它值得作为一个答案,因为它是一个完美的仅 XAML 解决方案,可以很好地自定义并且没有任何 hack。

其想法是将 Expander 控件放置在 ListBox 中,并将 Expander.IsExpanded 属性绑定到 ListBoxItem.IsSelected 属性。

这是一个现成的示例,您可以将其粘贴到 XAML 文件中并尝试一下:

<ListBox>
    <ListBox.Resources>
        <Style TargetType="{x:Type Expander}">
            <Setter Property="IsExpanded" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />
        </Style>
    </ListBox.Resources>
    <ListBox.Template>
        <ControlTemplate TargetType="{x:Type ListBox}">
            <ItemsPresenter />
        </ControlTemplate>
    </ListBox.Template>
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <ContentPresenter Content="{TemplateBinding Content}" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
    <Expander Background="Gray" Width="243" Header="Expander1">
        <StackPanel>
            <RadioButton Content="Eat Me" GroupName="Two" />
            <RadioButton Content="Eat Pork" GroupName="Two" />
            <RadioButton Content="Eat at Joe's" GroupName="Two" />
        </StackPanel>
    </Expander>
    <Expander Background="Gray" Width="243" Header="Expander2">
        <StackPanel>
            <RadioButton Content="Pork" GroupName="Two" />
            <RadioButton Content="Beef" GroupName="Two" />
            <RadioButton Content="Chicken" GroupName="Two" />
        </StackPanel>
    </Expander>
    <Expander Background="Gray" Width="243" Header="Expander3">
        <StackPanel>
            <RadioButton Content="Grill" GroupName="Two" />
            <RadioButton Content="Bake" GroupName="Two" />
            <RadioButton Content="Fry" GroupName="Two" />
        </StackPanel>
    </Expander>
</ListBox>

这曾经在这里:
http://forums.microsoft.com/MSDN/ShowPost。 aspx?PostID=3061227&SiteID=1
但forums.microsoft.com 似乎已经破产了。

在此页面上仍然可以找到它:
https://social.msdn.microsoft.com/Forums/en-US/a2988ae8-e7b8-4a62-a34f-b851aaf13886/windows-presentation-foundation-faq?forum=wpf
在标题“3.​​4 如何保持一组 Expander 控件中仅打开一个 Expander 控件?”

User "Dabblernl" posted this as a comment, but it deserves being an answer because it is a perfect XAML-only solution, nicely customizable and without any hacks.

The idea is to place Expander controls in a ListBox, and bind the Expander.IsExpanded property to the ListBoxItem.IsSelected property.

Here is a ready-made example that you can just paste into a XAML file and try it out:

<ListBox>
    <ListBox.Resources>
        <Style TargetType="{x:Type Expander}">
            <Setter Property="IsExpanded" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />
        </Style>
    </ListBox.Resources>
    <ListBox.Template>
        <ControlTemplate TargetType="{x:Type ListBox}">
            <ItemsPresenter />
        </ControlTemplate>
    </ListBox.Template>
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <ContentPresenter Content="{TemplateBinding Content}" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
    <Expander Background="Gray" Width="243" Header="Expander1">
        <StackPanel>
            <RadioButton Content="Eat Me" GroupName="Two" />
            <RadioButton Content="Eat Pork" GroupName="Two" />
            <RadioButton Content="Eat at Joe's" GroupName="Two" />
        </StackPanel>
    </Expander>
    <Expander Background="Gray" Width="243" Header="Expander2">
        <StackPanel>
            <RadioButton Content="Pork" GroupName="Two" />
            <RadioButton Content="Beef" GroupName="Two" />
            <RadioButton Content="Chicken" GroupName="Two" />
        </StackPanel>
    </Expander>
    <Expander Background="Gray" Width="243" Header="Expander3">
        <StackPanel>
            <RadioButton Content="Grill" GroupName="Two" />
            <RadioButton Content="Bake" GroupName="Two" />
            <RadioButton Content="Fry" GroupName="Two" />
        </StackPanel>
    </Expander>
</ListBox>

This used to be here:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3061227&SiteID=1
but forums.microsoft.com seems to have gone belly up.

It can still be found on this page:
https://social.msdn.microsoft.com/Forums/en-US/a2988ae8-e7b8-4a62-a34f-b851aaf13886/windows-presentation-foundation-faq?forum=wpf
under the title "3.4 How to keep only one Expander control opened in a group of Expander controls?"

凌乱心跳 2024-08-21 16:49:09

您可以添加一个值为“展开的扩展器”的依赖属性,然后可以使用您最喜欢的表达式绑定技术(类型转换器等)将“expanded”属性绑定到表达式“theExpandedProperty == this”。

You can add a dependency property whose value is "the expander that is expanded," and then you can bind the "expanded" property to the expression "theExpandedProperty == this" using your favorite expression binding technique (type converter, etc).

最终幸福 2024-08-21 16:49:09

这是在 WPF 中执行此操作的更详细方法,无需任何隐藏代码:

<UserControl.Resources>
    <ResourceDictionary>
        ...
        <Style TargetType="{x:Type Expander}">
            <Setter Property="IsExpanded" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
        </Style>

    </ResourceDictionary>

</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="{x:Null}" Margin="10">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ScrollViewer VerticalAlignment="Top" HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" VerticalContentAlignment="Top" BorderThickness="0,0,0,0" Grid.RowSpan="1" Grid.Row="0">
        <ListBox x:Name="OrdersListBox" BorderThickness="0" ItemContainerStyle="{StaticResource ShellThemeListBoxStyle}" 
                 IsSynchronizedWithCurrentItem="True" 
                 prism:RegionManager.RegionName="{x:Static uiCommon:RegionNames.WorkSheetsRegion}" Background="#00000000">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="typeData:WorkSheetsDetialsViewModel">
                    <local:WorkSheetsDetialsView/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </ScrollViewer>
    ...
</Grid>

<UserControl 
    x:Class="Module.ExcelDocumentManager.WorkSheets.WorkSheetsDetialsView"
    ...>
    <Expander>
        <Expander.Header>
            <TextBlock Text="{Binding HeaderInfo}" RenderTransformOrigin=".5,.5">
            </TextBlock>
        </Expander.Header>
        ...

    </Expander>
</UserControl>

Here is a more elaborate way to do it in WPF without any code behind:

<UserControl.Resources>
    <ResourceDictionary>
        ...
        <Style TargetType="{x:Type Expander}">
            <Setter Property="IsExpanded" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
        </Style>

    </ResourceDictionary>

</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="{x:Null}" Margin="10">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ScrollViewer VerticalAlignment="Top" HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" VerticalContentAlignment="Top" BorderThickness="0,0,0,0" Grid.RowSpan="1" Grid.Row="0">
        <ListBox x:Name="OrdersListBox" BorderThickness="0" ItemContainerStyle="{StaticResource ShellThemeListBoxStyle}" 
                 IsSynchronizedWithCurrentItem="True" 
                 prism:RegionManager.RegionName="{x:Static uiCommon:RegionNames.WorkSheetsRegion}" Background="#00000000">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="typeData:WorkSheetsDetialsViewModel">
                    <local:WorkSheetsDetialsView/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </ScrollViewer>
    ...
</Grid>

<UserControl 
    x:Class="Module.ExcelDocumentManager.WorkSheets.WorkSheetsDetialsView"
    ...>
    <Expander>
        <Expander.Header>
            <TextBlock Text="{Binding HeaderInfo}" RenderTransformOrigin=".5,.5">
            </TextBlock>
        </Expander.Header>
        ...

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