WPF自定义控件 - 未应用ItemsControl模板

Pat*_*ite 7 c# wpf

我正在构建一个派生自TabControl的自定义WPF控件.在ControlTemplate中,我使用ItemsControl来显示从模板绑定的列表(FileMenuItem类型的可观察集合).在程序执行期间,我在输出窗口中收到以下错误:

对于ItemsControl容器类型的项目,将忽略ItemTemplate和ItemTemplateSelector; 类型= 'FileMenuItem'

FileMenuItem类型派生自MenuItem.如果我将基类更改为DependencyObject,则实际运行代码并应用模板(这是一个选项).我搜索了错误,无法找到任何关于它的信息,是否有人在开发自定义控件时遇到此问题?即使我有一个解决方法,我想了解发生了什么,我认为使用MenuItem作为基类是一个更清洁的实现.

我可以发布更多代码,如果它会有所帮助.谢谢!

Joh*_*wen 7

DataTemplate(如ItemTemplate)的目的是为数据对象提供可视化.具体来说,它定义了一组要添加到可视树中的元素,而不是提供给ContentPresenter或ItemsPresenter的数据.在您的情况下,您的源列表是一组对象,这些对象已经能够直接添加到可视树中以便在UI中显示.

您可以在下面的简化示例中看到这一点,其中只有"Three"以红色显示,因为前两个项目是以可以由ComboBox直接显示的形式定义的.

<ComboBox>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" Foreground="Red"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
    <ComboBoxItem>One</ComboBoxItem>
    <ComboBoxItem>Two</ComboBoxItem>
    <sys:String>Three</sys:String>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

  • 解决这个问题最简单(也是最有效)的方法之一就是派生你自己的ItemsControl,并覆盖`IsItemItsOwnContainerOverride`方法返回false,这意味着由于John解释的问题,不会跳过DataTemplate. . (6认同)
  • 你可以采取很多不同的方式.您应该尝试决定是将对象项目视为控件(从UIElement派生)还是数据(INotifyPropertyChanged或DependencyObject),或者创建数据类和UI控件或DataTemplate.另一个可能的选项是派生的ItemsControl,它覆盖GetContainerForItemOverride和IsItemItsOwnContainerOverride,以便为每个项目使用FileMenuItem容器(ComboBox,ListBox等执行此操作). (5认同)