Home > Software design >  Creating a ListBox style Control with "Show X More"
Creating a ListBox style Control with "Show X More"

Time:01-16

I would like to create a type of control that will be able to see a narrowed and expanded list by some button, an expander or just a button, and also display some hidden items

I tried to create a style that would have a ListBox of a certain size (let's say it would be enough for 3 items)

And the Expander or some Button that would be below it would say how many more items there are

And give the option to expand and see everything or reduce and return to see 3 items

What I created here works pretty poorly and doesn't look good.

I would appreciate help on how to improve it or how to do it in a better and more correct way

<Style x:Key="CustomListBoxKey" TargetType="{x:Type ListBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <ItemsPresenter/>
                    <Expander x:Name="Expander" Grid.Row="1" Header="Show X More" ExpandDirection="Down"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding ElementName=Expander, Path=IsExpanded}" Value="False">
                        <Setter Property="MaxHeight" Value="80"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding ElementName=Expander, Path=IsExpanded}" Value="True">
                        <Setter Property="MaxHeight" Value="Infinity"/>
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

public List<string> Items { get; set; } = new() { "A", "B", "C", "D", "E", "F", "G", "H", "I" };

<Grid>
    <ListBox ItemsSource="{Binding Items}" Style="{StaticResource CustomListBoxKey}" VerticalAlignment="Top">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Path=.}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

CodePudding user response:

This is an improvement to your code, and it will give you what you asked for

<local:InvertableBooleanToVisibilityConverter x:Key="InvertableBooleanToVisibilityConverterKey"/>
<local:MathValueConverter x:Key="MathValueConverterKey"/>

<Style x:Key="CustomListBoxKey" TargetType="{x:Type ListBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <ItemsPresenter x:Name="ItemsPresenter"/>
                    <Expander 
                        x:Name="Expander" 
                        Grid.Row="1" 
                        ExpandDirection="Down">
                        <Expander.Header>
                            <StackPanel 
                                Orientation="Horizontal" 
                                Visibility="{Binding RelativeSource={RelativeSource AncestorType=Expander}, Path=IsExpanded, Converter={StaticResource InvertableBooleanToVisibilityConverterKey}}">
                                <TextBlock Text="Show "/>
                                <TextBlock 
                                    Text="{Binding RelativeSource={RelativeSource Self}, Path=DataContext.Items.Count, 
                                    Converter={StaticResource MathValueConverterKey},
                                    ConverterParameter=-2}">
                                </TextBlock>
                                <TextBlock Text=" More"/>
                            </StackPanel>
                        </Expander.Header>
                    </Expander>
                </Grid>
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding ElementName=Expander, Path=IsExpanded}" Value="False">
                        <Setter Property="MaxHeight" Value="80"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding ElementName=Expander, Path=IsExpanded}" Value="True">
                        <Setter Property="MaxHeight" Value="Infinity"/>
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

public class MathValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int.TryParse(parameter.ToString(), out var x);
        return (int)value   x;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class InvertableBooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is bool and true ? Visibility.Collapsed : Visibility.Visible;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
  •  Tags:  
  • wpf
  • Related