I am currently displaying a ListView
in a Flyout
of a DropDownButton
. I have an ObservableCollection
that is bound to the ListView
. During the app initialization, a method that clears the contents of the ObservableCollection
and adds some elements to it, is called, this should update the ListView
and show some elements on the UI, but an empty container is shown instead.
XAML:
<DropDownButton Content="Super long name that does not fit on the dropdown">
<DropDownButton.Flyout>
<Flyout Placement="Bottom" >
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="3"/>
<Setter Property="CornerRadius" Value="5"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<ListView
ItemsSource="{x:Bind _presenter.ViewModel.OutputDeviceViewModelList, Mode=OneWay}"
DisplayMemberPath="ListName"
SelectedValuePath="SelectedName"
CornerRadius="10"
SelectionMode="None"
IsItemClickEnabled="True"
ItemClick="OnMasterChannelDropdownSelectionChange"
/>
</Flyout>
</DropDownButton.Flyout>
</DropDownButton>
Main Window (List Initialization call):
public MainWindow()
{
this.InitializeComponent();
_presenter = new Presenter(Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread());
_controller = new Controller();
// Initialize states
_controller.GetDubwareDeviceInfo(); // Trigger a flow that ends up calling the UpdateOutputDevices on the Presenter
}
Presenter code:
public class Presenter
{
public Microsoft.UI.Dispatching.DispatcherQueue DispatcherQueue { get; }
public ViewModel ViewModel { get; } = new();
public void UpdateOutputDevices(List<OutputDeviceDs> outputDeviceDsList)
{
DispatcherQueue.TryEnqueue(() =>
{
ViewModel.OutputDeviceViewModelList.Clear();
ViewModel.OutputDeviceViewModelList.Add(new("", "SelectDevice", "None"));
foreach (OutputDeviceDs outputDeviceDs in outputDeviceDsList)
{
ViewModel.OutputDeviceViewModelList.Add(new(outputDeviceDs.Name, outputDeviceDs.Name, outputDeviceDs.Name));
}
Debug.WriteLine($" Updated output device list, outputDeviceDsList has {outputDeviceDsList.Count} elements and OutputDeviceViewModelList has {ViewModel.OutputDeviceViewModelList.Count} elements");
});
}
}
View model (contains the ObservableCollection):
public class ViewModel
{
public ViewModel() { }
public ObservableCollection<OutputDeviceViewModel> OutputDeviceViewModelList { get; set; } = new();
}
Model:
public class OutputDeviceViewModel
{
public string Id { get; set;}
public string SelectedName { get; set;}
public string ListName { get; set;}
public OutputDeviceViewModel(string id, string selectedName, string listName)
{
Id = id;
SelectedName = selectedName;
ListName = listName;
}
}
When the app is executed Debug print show that the list is populated with 3 elements
But an empty container is shown when the dropdown is open
Is only after interacting with other elements of the page that the list shows three elements.
Currently I have managed force the update of the ListView
by creating a non visible ListView
, that is bound to the same ObservableCollection
, at the same level of the DropDownButton
as such:
<ListView
Visibility="Collapsed"
ItemsSource="{x:Bind _presenter.ViewModel.OutputDeviceViewModelList, Mode=OneWay}"
/>
<DropDownButton Content="Super long name that does not fit on the dropdown">
<DropDownButton.Flyout>
<Flyout Placement="Bottom" >
...
...
...
With this workarround the list shows the 3 elements as soon as the ObservableCollection
is updated during intialization
Does anyone has any clue why this this workaround fixes the ListView
elements not updating as soon as the list is udpated?