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();
}
}