如何在Xaml中创建一个可收缩的stackpanel

本文关键字:一个 stackpanel Xaml 创建 | 更新日期: 2023-09-27 18:05:43

我的想法相当简单,我在很多地方都见过。我希望能够扩展和收缩基于点击按钮的项目列表。

交货

  • 列1
  • 列2
    • 子清单项1
    • 子清单项2
  • 3

只需单击listitem2,子条目就会消失。再次单击它或任何其他列表,属于该列表的子列表项将重新出现。

这是我到目前为止所做的(不工作)

频道。Xaml:

<UserControl
x:Class="InternetRadio.RadioChannels"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:InternetRadio"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">

<StackPanel x:Name="stationList" Orientation="Vertical">
    <Button x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content="&#xE700;" Width="50" Height="50" Background="Transparent" Click="HamburgerButton_click"/>
    <TextBlock x:Name="textBox" Text="Internet Radio Stations" Padding="50,0,0,0" Height="20px" />
    <ToggleButton x:Name="collapsableBtn" Content="DR Channels" Margin="50,0,0,0" Background="Transparent" Click="collapsableBtn_Click" />
        <StackPanel x:Name="RadioChannelsCollapsable" Visibility="Collapsed">
    <ItemsControl x:Name="tStack" Grid.Column="1" >
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                <Button Content="{Binding ItemName}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</StackPanel>

Channels.xaml.cs

private void collapsableBtn_Click(object sender, RoutedEventArgs e)
        {
            if(RadioChannelsCollapsable.Visibility == Visibility.Collapsed)
            {
                RadioChannelsCollapsable.Visibility = Visibility.Visible;
                RadioChannelsCollapsable.Children.ToList().ForEach(vis => vis.Visibility = Visibility.Visible);
            }
            else
            {
                RadioChannelsCollapsable.Visibility = Visibility.Collapsed;
                RadioChannelsCollapsable.Children.ToList().ForEach(vis => vis.Visibility = Visibility.Collapsed);
            }

只是为了清楚,这个usercontrol在splitView中是这样使用的:mainpage.xaml

<SplitView x:Name="radioChannelssplitview" DisplayMode="CompactOverlay" IsPaneOpen="False" CompactPaneLength="50" OpenPaneLength="250">
    <SplitView.Pane>
        <local:RadioChannels x:Name="myControl" Background="Gray"/>
    </SplitView.Pane>
    <SplitView.Content>
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <TextBlock x:Name="StationTitle" Text="Internet Radio" HorizontalAlignment="Center" VerticalAlignment="Top" Height="20px" />
            <TextBlock x:Name="ProgramTitle" Text="Welcome Page" HorizontalAlignment="Center" VerticalAlignment="Top" Height="20px" Margin="130,60,140,560" />
        </Grid>
    </SplitView.Content>
</SplitView>

        }

和我不能使它工作:(splitview打开和关闭很容易,但stackpanel不扩展和收缩在所有。请给我一个指针,在哪里或为什么我错了和/或指针,我应该如何做到这一点。提前感谢

如何在Xaml中创建一个可收缩的stackpanel

我宁愿尝试创建我自己的UserControl,可以扩展或不依赖于它的VisualState。我的快速和简单的例子:

MainPage.xaml:

<Page.Resources>
    <DataTemplate x:Key="MyItemTemplate">
        <local:MyItem></local:MyItem>
    </DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView ItemsSource="{Binding Items}" ItemTemplate="{StaticResource MyItemTemplate}" 
              SelectionMode="None" IsItemClickEnabled="True">
    </ListView>
</Grid>

MainPage.xamls.cs:

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }
}

ViewModel.cs:

public class ViewModel
{
    public ViewModel()
    {
        Items.Add(new MyItemViewModel("Item1"));
        Items.Add(new MyItemViewModel("Item2"));
        Items.Add(new MyItemViewModel("Item3"));
    }
    public ApplicationDataLocality ApplicationDataLocalityEnum { get; } =
           ApplicationDataLocality.Local;
    public FontStyle FontStyleEnum { get; } =
               FontStyle.Normal;
    public ObservableCollection<MyItemViewModel> Items { get; set; } = new ObservableCollection<MyItemViewModel>();
}

MyItem.xaml.cs:

<StackPanel Orientation="Vertical">
    <TextBlock Text="{Binding Title}" x:Name="TitleBlock"  Tapped="Title_OnTapped"/>
    <ListView ItemsSource="{Binding Items}" x:Name="ItemsBlock" ItemClick="Items_OnItemClick" IsItemClickEnabled="True"/>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Regular">
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsBlock" Storyboard.TargetProperty="Visibility" >
                        <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
            <VisualState x:Name="Expanded">
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsBlock" Storyboard.TargetProperty="Visibility" >
                        <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</StackPanel>

MyItem.xaml.cs:

public enum MyItemState
{
    Regular,
    Expanded
}
public sealed partial class MyItem : UserControl
{
    private MyItemState _state;
    public MyItemState State
    {
        get { return _state; }
        set
        {
            _state = value;
            VisualStateManager.GoToState(this, _state.ToString(), true);
        }
    }
    public MyItem()
    {
        InitializeComponent();
        State = MyItemState.Regular;
    }
    private void Title_OnTapped(object sender, TappedRoutedEventArgs e)
    {
        if (State == MyItemState.Regular)
        {
            State = MyItemState.Expanded;
        }
        else
        {
            State = MyItemState.Regular;
        }
    }
    private void Items_OnItemClick(object sender, ItemClickEventArgs e)
    {
        // action after subitem is clicked
    }
}

和MyItemViewModel:

public class MyItemViewModel
{
    public ObservableCollection<TextBlock> Items { get; set; } = new ObservableCollection<TextBlock>();
    public string Title { get; set; }
    public MyItemViewModel(string title)
    {
        Title = title;
        Items.Add(new TextBlock() { Text = "SubItem1" });
        Items.Add(new TextBlock() { Text = "SubItem2" });
        Items.Add(new TextBlock() { Text = "SubItem3" });
    }
}

每当你点击MyItem标题,它会改变它的状态-扩大或缩小它的子项(只有文本框只是为了保持简单-可能由另一个UserControl与任何视图你想),在这种情况下,我存储在另一个ListView。待办事项:更改样式和动画,使状态更改看起来更好等等。