I've got a DataGrid containing a TemplateColumn containing a combo box, which looks like:
<DataGridTemplateColumn Header="Initials" Width="50" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValuePath="Initials" DisplayMemberPath="Initials" ItemsSource="{Binding Path=DataContext.Drivers, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" >
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
This works, but it seems like the ItemSource is only loaded the first time a user tries to edit the combobox selection, instead of when the DataGrid loads. This means the client hangs for a few when a combobox is selected. I want this to happen when the rest of the DataGrid is loaded. Is there a way to do this?
Edit: Just tried enabling UI Virtualization on the box per this question, and it didn't help. I made the following test case that has the same issues. In the xaml:
<DataGrid Name="TestDataGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Initials" Width="50">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox VirtualizingStackPanel.IsVirtualizing="True" ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.CanContentScroll="True" SelectedValuePath="Initials" SelectedValue="{Binding Path=Initials, Mode=TwoWay, IsAsync=True}" DisplayMemberPath="Initials" ItemsSource="{Binding Path=DataContext.Drivers, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" >
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
In the window's code behind:
public TestWindow()
{
InitializeComponent();
var _context = new TestContext();
DataContext = _context;
TestDataGrid.ItemsSource = _context.Atms;
}
And in the data context:
public ObservableCollection<Driver> Drivers { get => drivers; set => drivers = value; }
public ObservableCollection<Driver> drivers;
private ListCollectionView atms;
public ListCollectionView Atms { get => atms; set => atms = value; }
public TestContext()
{
drivers = Driver.GetDriversToday();
var atms = AtmForecast.GetAtms(UpdateTotalCallback);
ListCollectionView collection = new ListCollectionView(atms);
Atms = collection;
}
public void UpdateTotalCallback(AtmForecast sender)
{
}
The driver list is super small too, ~5 entries, and it still freezes for a few seconds when opening the combo box at first. The one thing I have noticed is, in the debug output:
mincore\com\oleaut32\dispatch\ups.cpp(2126)\OLEAUT32.dll!00007FFE8D6A1924: (caller: 00007FFE8D6A1A5A) ReturnHr(1) tid(8648) 8002801D Library not registered.
'RoutesApp.exe' (Win32): Loaded 'C:\Windows\System32\oleacc.dll'. Symbols loaded.
'RoutesApp.exe' (Win32): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.20\Accessibility.dll'.
'RoutesApp.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.20\Accessibility.dll'. Symbols loaded.
This is the only output when a ComboBox is first clicked. Unsure if this dll can be manually loaded with the Window? I'm not sure how to do that if so.