WTF WPF TabControl? [英] WTF WPF TabControl?

查看:21
本文介绍了WTF WPF TabControl?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这是 WPF 中的一个错误(如果重要的话,v4.0),但已经晚了,也许我遗漏了一些东西.

I believe this to be a bug in WPF (v4.0 if it matters), but it is late, and maybe I'm missing something.

为了说明目的,我绑定了一个假示例:

I am binding to a fake example for illustrative purposes:

    <x:Array x:Key="SampleItems" Type="sys:String">
        <sys:String>Foo</sys:String>
        <sys:String>Bar</sys:String>
        <sys:String>Baz</sys:String>
    </x:Array>

这可以工作并显示三个具有相同标题和内容的标签:

This works and displays three tabs with the same header and content:

<TabControl ItemsSource="{StaticResource SampleItems}">
            <TabControl.ItemContainerStyle>
                <Style TargetType="TabItem">
                    <Setter Property="Header" Value="{Binding}" />
                    <Setter Property="Content" Value="{Binding}" />
                </Style>
            </TabControl.ItemContainerStyle>
        </TabControl>

但是,这会引发异常并显示消息错误 10 指定的元素已经是另一个元素的逻辑子元素.首先断开它.":

However, this throws an exception with the message "Error 10 Specified element is already the logical child of another element. Disconnect it first.":

<TabControl ItemsSource="{StaticResource SampleItems}">
    <TabControl.ItemContainerStyle>
        <Style TargetType="TabItem">
            <Setter Property="Header">
                <Setter.Value>
                    <!-- Anything here causes this problem. -->
                    <TextBlock Text="{Binding}"/>
                </Setter.Value>
            </Setter>
            <Setter Property="Content" Value="{Binding}" />
        </Style>
    </TabControl.ItemContainerStyle>
</TabControl>

请务必注意,这可以在任一 TextBlock 中的任何文本中重现.事实上,我可以用任何 XAML 替换标头 TextBlock 并获得此消息.我不知道如何解释这一点.任何想法,或者这只是一个错误?

It is important to note that this is reproducible with any text in either TextBlock. In fact, I can replace the header TextBlock with any XAML and get this message. I'm at a loss to explain this. Any ideas, or is this just a bug?

问题出现在 VS 设计器中,但这里也是运行时相关堆栈跟踪的一部分:

The problem appears in the VS designer, but here is a portion of the relevant stack trace at runtime as well:

   at System.Windows.FrameworkElement.ChangeLogicalParent(DependencyObject newParent)
   at System.Windows.FrameworkElement.AddLogicalChild(Object child)
   at System.Windows.Controls.HeaderedContentControl.OnHeaderChanged(Object oldHeader, Object newHeader)
   at System.Windows.Controls.HeaderedContentControl.OnHeaderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.StyleHelper.ApplyStyleOrTemplateValue(FrameworkObject fo, DependencyProperty dp)
   at System.Windows.StyleHelper.InvalidateContainerDependents(DependencyObject container, FrugalStructList`1& exclusionContainerDependents, FrugalStructList`1& oldContainerDependents, FrugalStructList`1& newContainerDependents)
   at System.Windows.StyleHelper.DoStyleInvalidations(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle)
   at System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache)
   at System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at System.Windows.Controls.ItemsControl.ApplyItemContainerStyle(DependencyObject container, Object item)
   at System.Windows.Controls.ItemsControl.MS.Internal.Controls.IGeneratorHost.PrepareItemContainer(DependencyObject container, Object item)
   at System.Windows.Controls.ItemContainerGenerator.System.Windows.Controls.Primitives.IItemContainerGenerator.PrepareItemContainer(DependencyObject container)
   at System.Windows.Controls.Panel.GenerateChildren()

推荐答案

基本上,您所做的是为每个 TabItem 分配完全相同的 TextBlock 实例.在第一次迭代时,TextBlock 被添加到第一个 TabItem.在第二次迭代中,非常相同 TextBlock 被添加到可视化树中.您看到的错误消息试图告诉您 TextBlock 不能有两个父级(某处有一个笑话).

Basically what you are doing is assigning the very same instance of a TextBlock to each TabItem. On the first iteration, the TextBlock is added to the first TabItem. On the second iteration, the very same TextBlock is added to the visual tree. The error message you see is trying to tell you that the TextBlock can't have two parents (there is a joke there somewhere).

可以为这些设置模板.模板指示 TabItem 为每个创建的项目创建一组您想要的任何视觉效果.

You can set a template for these, however. A template instructs the TabItem to create a new set of whatever visual you want per item created.

<TabControl ItemsSource="{StaticResource SampleItems}">
    <TabControl.ItemContainerStyle>
        <Style TargetType="TabItem">
            <Setter Property="HeaderTemplate">
                <Setter.Value>
                    <DataTemplate>
                         <TextBlock Text="{Binding}"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Content" Value="{Binding}" />
        </Style>
    </TabControl.ItemContainerStyle>
</TabControl>

这篇关于WTF WPF TabControl?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆