Need some pointers on XAML styling for a collapsed bullet point list with a hyperlink to display all data items, i.e. show only the first option by default, with some hyperlink text which when clicked, would display the remaining items in the list. E.g.:
Collapsed List
Option 1
That said, here's some code
It's not terribly difficult to do what you're asking. You just need to create a custom user control. Below is the Xaml and Xaml.cs for a custom user control I made for you
SampleCollapsedList.xaml.cs
public partial class SampleCollapsedList : UserControl, INotifyPropertyChanged { public bool IsExpanded { get; set; } public string FirstItem { get { return ListItems != null && ListItems.Count > 0 ? ListItems?.First() : string.Empty; } } public ObservableCollection<string> ListItems { get { return (ObservableCollection<string>)GetValue(ListItemsProperty); } set { SetValue(ListItemsProperty, value); } } public static readonly DependencyProperty ListItemsProperty = DependencyProperty.Register(nameof(ListItems), typeof(ObservableCollection<string>), typeof(SampleCollapsedList), new PropertyMetadata(null,CollectionUpdated)); public event PropertyChangedEventHandler PropertyChanged; public SampleCollapsedList() { InitializeComponent(); } private static void CollectionUpdated(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is SampleCollapsedList sampleCollapsedList) { sampleCollapsedList.OnPropertyChanged(nameof(FirstItem)); } } private void OnHyperlinkClicked(object sender, RoutedEventArgs e) { IsExpanded = !IsExpanded; OnPropertyChanged(nameof(IsExpanded)); } private void OnPropertyChanged(string propName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); } }
SampleCollapsedList.xaml
<UserControl x:Class="WpfApp1.SampleCollapsedList" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" x:Name="self"> <UserControl.Resources> <local:BoolToVisConverter x:Key="BoolToVisibilityConverter" /> </UserControl.Resources> <Grid Height="250" Width="500"> <StackPanel Orientation="Vertical" Visibility="{Binding Path=IsExpanded, ElementName=self, Converter={StaticResource ResourceKey=BoolToVisibilityConverter}, ConverterParameter=opposite}"> <TextBlock Text="{Binding Path=FirstItem, ElementName=self}" /> <TextBlock><Hyperlink Click="OnHyperlinkClicked">Click Me</Hyperlink></TextBlock> </StackPanel> <ListBox Visibility="{Binding Path=IsExpanded, ElementName=self, Converter={StaticResource ResourceKey=BoolToVisibilityConverter}}" ItemsSource="{Binding Path=ListItems, ElementName=self}" BorderThickness="0"> <ListBox.ItemTemplate> <DataTemplate> <TextBlock><Run>- </Run><Run Text="{Binding Path=.}" /></TextBlock> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </UserControl>
Also a simple converter to make the hide show magic happen
using System; using System.Globalization; using System.Windows.Data; using System.Windows; namespace WpfApp1 { public class BoolToVisConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if(parameter is string param && param.ToLower().Contains("opposite")) { return (bool)value ? Visibility.Collapsed : Visibility.Visible; } else { return (bool)value ? Visibility.Visible : Visibility.Collapsed; } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }