0
votes

I have a listbox with a usercontrol set as the listbox item. within this listbox I have a few grids and two buttons.

<Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch">
    <Grid.RowDefinitions>
        <RowDefinition Height="120" />
        <RowDefinition x:Name="personDetailHolder" Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="92.915" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <StackPanel Grid.RowSpan="2"
                Grid.ColumnSpan="2"
                Margin="0,0,-0.042,0"
                Orientation="Vertical"
                d:LayoutOverrides="Height">
        <Grid Height="117" Margin="3,0,0,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="117" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Rectangle  />
            <!-- removed for brevity -->

            <Button x:Name="btnViewDetails"
                    Width="106"
                    Height="24"
                    Margin="0,0,3,6"
                    HorizontalAlignment="Right"
                    VerticalAlignment="Bottom"
                    Click="btnDetails_Click"
                    Foreground="#FFFBCE2F"
                    Style="{StaticResource ViewDetailsButton}" />
            <!--  Detail section  -->
            <Grid x:Name="personDetail"
                  Grid.Row="1"
                  MinHeight="365"
                  Margin="0,0,5,-376"
                  VerticalAlignment="Bottom"
                  RenderTransformOrigin="0.5,0.5"
                  Visibility="Collapsed">
                <Rectangle />
                <!--  removed for brevity -->   

                <Button x:Name="btnCloseDetails"
                        Width="123"
                        Height="24"
                        Margin="0,8,8,0"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Top"
                        Click="btnDetails_Click"
                        Foreground="#FFFBC42F"
                        Style="{StaticResource CloseDetailsButton}" />

            </Grid>
        </Grid>
    </StackPanel>
</Grid>

The click event btnDetails_Click call an event in the code behind of the user control

private void btnDetails_Click(object sender, System.Windows.RoutedEventArgs e)
{
    UIPanelControl cp = new UIPanelControl();
    cp.CheckDetailPanelStatus(this.personDetail, this.personDetailHolder, this.btnViewDetails, this.btnCloseDetails, this.detailAnimation);
}

which calls the method

public void CheckDetailPanelStatus(Grid panelName, RowDefinition rowName, Button openButtonName, Button closeButtonName, Storyboard animi)
{
    if (panelName.Visibility == System.Windows.Visibility.Visible)
    {
        panelName.Visibility = System.Windows.Visibility.Collapsed;
        rowName.Height = new GridLength(0);
        openButtonName.Visibility = System.Windows.Visibility.Visible;
        closeButtonName.Visibility = System.Windows.Visibility.Collapsed;
    }
    else
    {
        panelName.Visibility = System.Windows.Visibility.Visible;
        rowName.Height = new GridLength(380);
        openButtonName.Visibility = System.Windows.Visibility.Collapsed;
        closeButtonName.Visibility = System.Windows.Visibility.Visible;
        animi.Begin();

    }
}

The goal here is to return to the user a list of results. The user can then click on the View additional details buttons expands a second section which displays more details about the selected record. I'm using MVVM approach so the command goes to the VM to facilitate the second record population. Since the animations, visibility etc was contained to the view I decided to keep those events in the view code behind.

This solution partially works in that when I click on the button the section does expand for the selected listbox item. However, if I scroll down to other results I will find other listbox items intermittently expanded. There is no repeatable pattern on this ( i.e. every 5th item or every other record) And I have also seen instances where if I select the first record and expand it then scroll down to the next record and back up the first record has been reset back to collapsed.

I'm stumped as to what may be causing this issue.

Can anyone provide any insight into why I am seeing this occur or how to prevent this from occurring?

3

3 Answers

1
votes

What you are seeing is a result of the listbox using object reuse to save memory and improve performance, a similar thing may occur within a GridView too. What the the control does is create X ListBoxItems and reuses these containers when their data items go out of view (Loaded/Unloaded). So if you change the look of the container, it will change the look of all the data item who share the container.

To fix the issue you can either; Handle the Loaded/Unloaded events of the ListBoxItem and fix the UI when the Unloaded event fires. Or, make the items you have bound to the List Selection aware and have them change the ListBoxItem look, so when they are Loaded/Unloaded the binding engine will take care of resetting the UI.

0
votes

Rather than change the visibility with the command

panelName.Visibility = System.Windows.Visibility.Collapsed;

you want to set the visibility in the xaml to something like

    <Grid x:Name="personDetail"
          Grid.Row="1"
          MinHeight="365"
          Margin="0,0,5,-376"
          VerticalAlignment="Bottom"
          RenderTransformOrigin="0.5,0.5"
          Visibility="{Binding PersonDetailVisibility}">

Assuming you have the property changed event handler wired in something like:

        PropertyChanged += new
        PropertyChangedEventHandler(PersonDetailViewModel_PropertyChanged);

Then after changing your PersonDetailVisibility property in the VM, you need to raise the property changed event

            this.RaisePropertyChanged(() => this.PersonDetailVisibility);
0
votes

I think this can be better implemented using VisualStates rather than setting the properties manually on the click event.

Just add two visual states in the template of your list item, one for "ShowDetails" and one for "HideDetails". you can then use the behavior GoToVisualStateBehavior to flip between them on the click of the button (which, i think, should be a ToggleButton).

Otherwise, you can use an Expander button to implement this.

Hope this helps :)