Rac*_*hel 10 wpf tabcontrol z-index tabitem
问题
 
我有一个自定义标签控件,使用与ViewModel绑定的Chrome形状标签.由于形状,边缘重叠一点.我有一个函数设置tabItem的ZIndex,TabControl_SelectionChanged它可以正常选择选项卡和拖放选项卡,但是当我通过中继命令添加或关闭选项卡时,我得到了不寻常的结果.有没有人有任何想法?
默认视图:
 
  
删除标签:
 
  
连续添加2个或更多Tab:
 
  
一次添加超过1个选项卡将不会重置其他最近添加的选项卡的zindex,因此它们会在右侧的选项卡后面,并且关闭选项卡无法正确呈现替换它的SelectedTab的ZIndex并且它显示在选项卡右侧.
用于设置ZIndex的代码
private void PrimaryTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.Source is TabControl)
        {
            TabControl tabControl = sender as TabControl;
            ItemContainerGenerator icg = tabControl.ItemContainerGenerator;
            if (icg.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
            {
                foreach (object o in tabControl.Items)
                {
                    UIElement tabItem = icg.ContainerFromItem(o) as UIElement;
                    Panel.SetZIndex(tabItem, (o == tabControl.SelectedItem ? 100 :
                        90 - tabControl.Items.IndexOf(o)));
                }
            }
        }
    }
通过使用断点,我可以看到它正确地将ZIndex设置为我想要的,但布局不显示更改.我知道有些变化是有效的,因为如果它们都没有工作,那么标签边缘将被颠倒(右边的标签将被绘制在左边的标签之上).单击选项卡将正确设置所有选项卡的zindex(包括应在顶部绘制的选项卡),拖放它们以重新排列它们也可以正确渲染(删除并重新插入选项卡项).我能想到的唯一区别是我使用MVVM设计模式和添加/关闭选项卡是中继命令的按钮.
有谁知道为什么会发生这种情况以及如何解决它?
ps我尝试在我的ViewModel中设置一个ZIndex并绑定到它,但是当通过relay命令添加/删除选项卡时会发生同样的事情.
谢谢安倍,你的第二条评论引导我解决问题!
我添加tabItem.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);到循环的每次迭代.
我仍然有兴趣学习是否有其他人找到解决方法而不刷新每个变化的每个tabItem.我尝试在循环结束时刷新整个选项卡控件,但这只适用于关闭选项卡,而不是添加它们.我知道Panel.ZIndex设置正确,它只是在渲染时不尊重该属性.
编辑:上面的代码行在拖动/删除标签时会导致异常闪烁,这些标签会短暂显示被拖动标签后面的标签.我将代码移动到一个单独的函数,并以较低的调度程序优先级调用它,这解决了问题.最终代码如下:
private void PrimaryTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.Source is TabControl)
        {
            TabControl tabControl = sender as TabControl;
            tabControl.Dispatcher.BeginInvoke(
                new Action(() => UpdateZIndex(sender as TabControl)),
                DispatcherPriority.Background);
        }
    }
    private void UpdateZIndex(TabControl tabControl)
    {
        ItemContainerGenerator icg = tabControl.ItemContainerGenerator;
        if (icg.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
        {
            foreach (object o in tabControl.Items)
            {
                UIElement tabItem = icg.ContainerFromItem(o) as UIElement;
                if (tabItem != null)
                {
                    // Set ZIndex
                    Panel.SetZIndex(tabItem, (o == tabControl.SelectedItem ? 100 :
                        90 - tabControl.Items.IndexOf(o)));
                }
            }
        }
    }