I'm using
<ListBox ItemsSource="{Binding MyItems}"
Height="500"
HorizontalAlignment="Stretch"/>
When I populate MyItems
from the view model, everything works as expected. But when I then use
<ContentControl Content="{Binding LeftPanel}"/>
Assign LeftPanel
to something else and switch back, I get this error:
System.InvalidOperationException: 'An anchor control must be a visual descendent of the ScrollContentPresenter.'
This only happens when I manually fill the list, not changing it (it's blank at the beginning). But I think that's just because there is no scrolling when the list is empty.
I should also mention, the list info is read async and I use this to populate it:
void FillListBox(string[] files)
{
Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
{
CreateListboxItems(files);
});
}
private void CreateListboxItems(string[] files)
{
MyItems.Clear();
int length = files.Length;
for (int i = 0; i < length; i++)
{
ListBoxItem item = CreateListboxItem(files[i]);
RenderFrameItems.Add(item);
}
}
ListBoxItem CreateListboxItem(string filePath)
{
Avalonia.Media.FontStyle fontStyle = File.Exists(filePath) ? Avalonia.Media.FontStyle.Normal : Avalonia.Media.FontStyle.Italic;
ListBoxItem response = new ListBoxItem()
{
Content = filePath,
FontStyle = fontStyle,
};
return response;
}
I also tried putting the list into its own scroll view, but same result.
EDIT:
Using ObservableCollection<string>
rather than ObservableCollection<ListBoxItem>
works, but I don't get the formatting I want
I solved it like this:
Instead of using ObservableCollection<ListBoxItem>
I created my own class:
public class FileListItem
{
public string Filename { get; set; }
public FontStyle FontStyle { get; set; }
public FileListItem(string filename, FileStatus status)
{
FontStyle = status == FileStatus.Existing ? FontStyle.Normal : FontStyle.Italic;
Filename = filename;
}
}
In the ViewModel use:
private ObservableCollection<FileListItem> _fileListItems;
public ObservableCollection<FileListItem> FileListItems
{
get => _fileListItems;
set => SetProperty(ref _fileListItems, value);
}
And then used a DataTemplate
to format the ListBoxItems
.
<ListBox ItemsSource="{Binding FileListItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Filename}" FontStyle="{Binding FontStyle}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I know the original Post did not include enough information, but here is the gist:
ObservableCollection<ListBoxItem>
- which I think is the natural approach - doesn't seem to work. DataTemplateBinding
using a custom class does.
The getter, setter seems to be essential, but I haven't tested removing the private var.
Complete description:
https://docs.avaloniaui.net/docs/guides/data-binding/how-to-bind-to-a-collection