我有一个DataTemplate
正在列出combobox
列表中的~7,000个项目。目前ItemsSource
绑定到DataTemplate
的数据上下文中的属性,但是这意味着对于DataTemplate
的每个实例,系统正在加载所有7k对象,这会减慢系统相当多。
理想情况下,我希望能够加载一次列表并将其用于所有实例。对我来说,显而易见的解决方案是使用Window.Resources
部分中定义的资源。但是我无法弄清楚这应该如何工作,更重要的是,应该如何通过MVVM模式填充该资源。
为每个ItemsSource
实例加载DataTemplate
的当前代码
<DataTemplate>
<ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding ItemsSource}" />
</DataTemplate>
尝试解决问题:
<Window.Resources>
<ResourceDictionary>
<sys:Object x:Key="ItemItemsSource" />
</ResourceDictionary>
</Window.Resources>
<DataTemplate>
<ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding Source={StaticResource ItemItemsSource}}" />
</DataTemplate>
每个DataTemplate都有自己的DataContext,这意味着数据模板的每个实例都有自己的ItemsSource
,它将填充在DataContext初始化器中。
在我的脑海中解决这个问题的理想方法是在窗口的DataContext
/ VM中拥有一个属性,它们也与Combobox绑定。这可能吗?类似的东西:
public class WindowsViewModel
{
public List<Object> SharedItemSource { get; set; }
}
<DataTemplate>
<ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding <Some Binding To SharedItemSource>}" />
</DataTemplate>
答案 0 :(得分:2)
减速在哪里?
如果是在显示ComboBox的弹出窗口时,也许您可以尝试使用这样的虚拟化:
<DataTemplate>
<ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding ItemsSource}">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</DataTemplate>
答案 1 :(得分:1)
为您的窗口创建一个MainViewModel或者控制所有组合框的内容,
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>
答案 2 :(得分:0)
如果您在VM中定义了属性,那么当您将其实例化并且作为所有组合框的源时,它将只加载一次..并非每个组合框都创建其itemsSource ..它只是消耗它来生成它items ..所以无论你将itemsSource作为Resource还是在Datacontext中都是同一件事。