I am using two ListBox elements. One is the parent (BucketListBox), which decides what is supposed to be displayed in child. Child (ObjectListBox) is in multi-select mode. Once I choose particular elements in child, I shift to another parent, the child ListBox is updated with new choices.
When the user shifts back to a previously browsed parent, he should be able to see the old choices in the child that he had selected then. I am maintaining a list of the items user selects in child. I want to use this list to change background color of those elements he had previously selected.
As of now, those elements are still selected, but not shown in UI.
Here is my XAML code for the parent:
<ListBox Grid.Row="1" x:Name="BucketListBox" HorizontalContentAlignment="Stretch" SelectionChanged="BucketListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<RelativePanel Grid.Row="0">
<TextBlock x:Name="BucketNameLabel" x:Uid="NameLabel"/>
<TextBlock Grid.Row="0" x:Name="BucketNameTextBlock" RelativePanel.AlignBottomWith="BucketNameLabel" RelativePanel.RightOf="BucketNameLabel" Text="{Binding BucketName}" Margin="10,10,10,10"/>
</RelativePanel>
<RelativePanel Grid.Row="1">
<TextBlock x:Name="BucketCreationDateLabel" FontSize="12" x:Uid="CreationDateLabel" HorizontalAlignment="Right"/>
<TextBlock x:Name="BucketCreationDateTextBlock" FontSize="12" RelativePanel.RightOf="BucketCreationDateLabel" RelativePanel.AlignBottomWith="BucketCreationDateLabel" Text="{Binding BucketCreationDate}" Margin="10,10,10,10" HorizontalAlignment="Right" />
</RelativePanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
Code for child ListBox:
<ListBox Grid.Row="1" Grid.Column="1" x:Name="ObjectListBox" HorizontalContentAlignment="Stretch" SelectionMode="Multiple">
<ListBox.ItemTemplate >
<DataTemplate >
<Grid Margin="10,10,10,10">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<RelativePanel Grid.Row="0">
<TextBlock x:Name="NameLabel" x:Uid="NameLabel" Margin="10,10,10,10" />
<TextBlock x:Name="ObjectNameTextBlock" Text="{Binding ObjectName}" RelativePanel.RightOf="NameLabel" RelativePanel.AlignBottomWith="NameLabel" Margin="10,10,10,10" />
</RelativePanel>
<RelativePanel Grid.Row="1">
<TextBlock x:Name="SizeLabel" FontSize="12" x:Uid="SizeLabel"/>
<TextBlock x:Name="ObjectSize" FontSize="12" Margin="10,10,10,10" Text="{Binding Path=ObjectSize}" RelativePanel.RightOf="SizeLabel" RelativePanel.AlignBottomWith="SizeLabel"/>
</RelativePanel>
<RelativePanel Grid.Row="2">
<TextBlock x:Name="ObjectModificationDateLabel" FontSize="12" x:Uid="ModificationDateLabel" Margin="10,10,10,10" HorizontalAlignment="Right"/>
<TextBlock x:Name="ObjectModificationDateTextBlock" FontSize="12" Text="{Binding ObjectLastModificationDate}" Margin="10,10,10,10" RelativePanel.RightOf="ObjectModificationDateLabel" RelativePanel.AlignBottomWith="ObjectModificationDateLabel" HorizontalAlignment="Right"/>
</RelativePanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And here is the code for updating ListBoxItem: (called whenever the user clicks on a new item in parent ListBox)
private void UpdateListBoxWithSelectedItems()
{
List<S3ObjectInfoHolder> currentList = (List<S3ObjectInfoHolder>)ObjectListBox.ItemsSource; //Getting the total elements being displayed in the current child list box
foreach (S3ObjectInfoHolder entry in listOfObjectsToTransfer) //listOfObjectsToTransfer is the list of all the entries from all the parents selected so far. So the intersection of currentList with this list gives the ones that are to be colored on UI so as the user knows the items are still selected
{
for (int i = 0; i < currentList.Count(); i++)
{
if (currentList[i].ObjectName.Equals(entry.ObjectName))
{
ObjectListBox.SelectedItems.Add(entry);
Debug.WriteLine("Selected Item:" + entry.ObjectName);
}
}
}
List<object> selectedItem = ObjectListBox.SelectedItems.ToList();
foreach (object item in selectedItem)
{
ListBoxItem selectedListBoxItem = ObjectListBox.ItemContainerGenerator.ContainerFromItem((S3ObjectInfoHolder)item) as ListBoxItem;
if(selectedListBoxItem!=null) selectedListBoxItem.Background = new SolidColorBrush(Colors.Turquoise);
}
}
selectedListBoxItem!=null fails, and the line is skipped. And lastly, here is the code for the binding class:
class S3ObjectInfoHolder
{
private string key;
private string bucketName;
private long size;
private string isObjectAFolder;
private string objectLastModificationDate;
public S3ObjectInfoHolder(string key, string bucketName)
{
this.key = key;
this.bucketName = bucketName;
isObjectAFolder = isObjectAFolderOrAFile(key);
}
private string isObjectAFolderOrAFile(string key)
{
if (key[key.Length - 1] == '/')
{
return "is a Folder";
}
else
{
return "is a File";
}
}
public string ObjectName
{
get
{
return key;
}
set
{
key = value;
}
}
public long ObjectSize
{
get
{
return size;
}
set
{
size = value;
}
}
public string ObjectIsFolder
{
get
{
return isObjectAFolder;
}
set
{
isObjectAFolder = value;
}
}
public string BucketName
{
get
{
return bucketName;
}
set
{
bucketName = value;
}
}
public string ObjectLastModificationDate
{
get
{
return objectLastModificationDate;
}
set
{
objectLastModificationDate = value;
}
}
}