c# uwp uwp-xaml

c# - wpf dock



cómo hacer un stackpanel contraíble en Xaml (1)

Prefiero tratar de crear mi propio UserControl que se puede expandir o no dependiendo de su VisualState. Mi muestra rápida y simple:

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

y 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" }); } }

cada vez que haga clic en el título de MyItem, cambiará su estado: expandir o reducir sus subítems (solo TextBoxes para simplificar) mediante otro UserControl con la vista que desee) que en este caso almaceno en otro ListView. Tarea: cambie los estilos y las animaciones para que el cambio de estado se vea mejor y así sucesivamente.

Mi idea es bastante simple y la he visto en muchos lugares. Quiero poder expandir y contratar una lista de elementos en función de un clic en un botón.

ex

  • listitem 1
  • listitem 2
    • Sublista elemento 1
    • Sublista elemento 2
  • listItem 3

simplemente haga clic en Listitem 2 y los elementos de la lista secundaria desaparecerán. haga clic de nuevo o cualquier otro elemento de lista y el elemento de la lista secundaria que pertenece a ese elemento de lista debe reaparecer.

esto es lo que hice hasta ahora (No funciona)

Channels.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); }

solo para que quede claro que este control de usuario se usa así en una vista dividida: 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> }

y no puedo hacer que funcione :( la vista dividida se abre y cierra fácilmente, pero el panel de distribución no se expande ni se contrae en absoluto. Por favor, denme un puntero a dónde o por qué me equivoco y / o un indicador de cómo debería estar haciendo esto . Gracias por adelantado