在DataTemplate中使用MVVM中的窗口资源

时间:2013-09-27 09:16:02

标签: c# wpf mvvm

我有一个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初始化器中。

更新2

在我的脑海中解决这个问题的理想方法是在窗口的DataContext / VM中拥有一个属性,它们也与Combobox绑定。这可能吗?类似的东西:

public class WindowsViewModel
{
     public List<Object> SharedItemSource { get; set; }
}

<DataTemplate>          
    <ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding <Some Binding To SharedItemSource>}" />          
</DataTemplate>

3 个答案:

答案 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中都是同一件事。