Reputation: 4922
I have a DataTemplate
that is loading a list of ~7000 items in a list for a combobox
. Currently the ItemsSource
is bound to a property in the data context of the DataTemplate
, however this means that for each instance of the DataTemplate
the system is loading all 7k objects, which is slowing down the system by quite a bit.
Ideally I want to be able to load the list once and use it for all instances. The obvious solution to me is using a resource defined in the Window.Resources
section. However I can't figure out how this should work, and more importantly, how that resource should be populated via the MVVM pattern.
Current code which loads the ItemsSource
for each DataTemplate
instance
<DataTemplate>
<ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding ItemsSource}" />
</DataTemplate>
Attempt at solving the problem:
<Window.Resources>
<ResourceDictionary>
<sys:Object x:Key="ItemItemsSource" />
</ResourceDictionary>
</Window.Resources>
<DataTemplate>
<ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding Source={StaticResource ItemItemsSource}}" />
</DataTemplate>
Each DataTemplate has its own DataContext which means each instance of the data template has its own ItemsSource
, which will populate at DataContext initialiser.
The ideal way in my mind to solve this is to have a property in the DataContext
/VM of the Window that they Combobox is bound too. Is this possible? Something like:
public class WindowsViewModel
{
public List<Object> SharedItemSource { get; set; }
}
<DataTemplate>
<ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding <Some Binding To SharedItemSource>}" />
</DataTemplate>
Upvotes: 0
Views: 490
Reputation: 12533
Create a MainViewModel for your window or what ever control all your combobox's are in ,
cs:
public class MainViewModel
{
private List<object> _itemsSource;
public List<object> ItemsSource
{
get { return _itemsSource; }
set { _itemsSource = value; }
}
}
xaml:
<DataTemplate>
<ComboBox SelectedItem="{Binding SelectedItem}"
ItemsSource="{Binding Path=DataContext.ItemsSource,
RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>
</DataTemplate>
Upvotes: 1
Reputation: 108
Where is the slow down ?
If it is when you show the ComboBox's popup, maybe you can try to use virtualization like this :
<DataTemplate>
<ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding ItemsSource}">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</DataTemplate>
Upvotes: 2
Reputation: 18580
If you have property defined in VM, then that will be loading just once when you will be instantiating it and be served as source for all the comboboxes.. not every combobox create its itemsSource.. it just consume it to generate its items.. so whether you put your itemsSource as Resource or in Datacontext is one and the same thing here.
Upvotes: 0