Lightness Lightness - 4 months ago 11
C# Question

How to implement the visual state in a ListBox

Let's have a

xaml
:

<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid IsItemsHost="True" Rows="2"></UniformGrid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>


If the height of the window to
500px
UniformGrid
findings in
2 lines
, and if more then
700px
3 lines
. How to implement this?

Answer

There are multiple possibilities. The most straightforward using binding and event in the view:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string property = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));

    public int Rows { get; private set; } = 3;

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    void ListBox_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        Rows = ((ListBox)sender).ActualHeight > 700 ? 4 : 3;
        OnPropertyChanged(nameof(Rows));
    }
}

xaml:

<ListBox SizeChanged="ListBox_SizeChanged">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="{Binding Rows}" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBoxItem>1</ListBoxItem>
    <ListBoxItem>2</ListBoxItem>
    <ListBoxItem>3</ListBoxItem>
    <ListBoxItem>4</ListBoxItem>
    <ListBoxItem>5</ListBoxItem>
    <ListBoxItem>6</ListBoxItem>
    <ListBoxItem>7</ListBoxItem>
    <ListBoxItem>8</ListBoxItem>
</ListBox>

Resize the window to see how it switches between 3 and 4 rows once size of ListBox is bigger than 700.