none
WPF,用代码动态添加TabItem到TabControl中(TabItem应用了样式,并且添加了一个UserControl的View),无法呈现预计的View RRS feed

  • 问题

  • 1.出问题的写法:


            private void CaseSheetNew_Click(object sender, RoutedEventArgs e)
            {
                //Zeta_tabWork 为TabControl ;CaseSheetView 为UserControl的View
                TabItem ti = new TabItem();

                /*下面这两句在这个位置的话,最后 Zeta_tabWork.SelectedItem = ti 并不能达到选中ti的效果;

                   需要人工鼠标去点击这个TabItem才能让其正真选中并且呈现CaseSheetView

                */
                Style tabStyle = (Style)this.FindResource("ZetaTabItemStyle");
                ti.Style = tabStyle;

                DataTemplate tabheaderStyle = (DataTemplate)this.FindResource("ZetaTabItemHeaderTemplate");
                ti.HeaderTemplate = tabheaderStyle;

                CaseSheetView csv = new CaseSheetView();
                ti.Content = csv;
               
                ti.IsSelected = false;
                string sHeader = "新开案_1";
                ti.Width = 120;
                ti.Header = sHeader;
               
                int iindex = Zeta_tabWork.Items.Add(ti);
                Zeta_tabWork.SelectedItem = ti;
         
            }

    2.下面这样写,就会正常显示:


            private void CaseSheetNew_Click(object sender, RoutedEventArgs e)
            {
                //Zeta_tabWork 为TabControl ;CaseSheetView 为UserControl的View
                TabItem ti = new TabItem();

                DataTemplate tabheaderStyle = (DataTemplate)this.FindResource("ZetaTabItemHeaderTemplate");
                ti.HeaderTemplate = tabheaderStyle;

                CaseSheetView csv = new CaseSheetView();
                ti.Content = csv;
               
                ti.IsSelected = false;
                string sHeader = "新开案_1";
                ti.Width = 120;
                ti.Header = sHeader;
               
                int iindex = Zeta_tabWork.Items.Add(ti);
                Zeta_tabWork.SelectedItem = ti;

                /*下面这两句在这个位置的话,即在 Zeta_tabWork.SelectedItem = ti 之后,选中ti的才正常

                 即直接就会展示了CaseSheetView !!!

                */
                Style tabStyle = (Style)this.FindResource("ZetaTabItemStyle");
                ti.Style = tabStyle;

         
            }

    对比上面的代码行的先后顺序,确定是样式“ZetaTabItemStyle” 导致问题的产生,现在将样式ZetaTabItemStyle贴出下,请高手参详下是哪个细节的问题导致如此的:

       <Style  x:Key="ZetaTabItemStyle"  TargetType ="{x:Type TabItem }">
            <Setter Property="Foreground" Value="{StaticResource BaseColor10Key}"/>
            <Setter Property="Background" Value="{StaticResource BaseColor7Key}"/>
            <Setter Property="BorderBrush" Value="{StaticResource BaseColor4Key}"/>
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
            <Setter Property="ToolTip" Value="{Binding ToolTip}"/>
            <Setter Property="Padding" Value="2,1,2,1"/>
            <Setter Property="Margin" Value="2,3,-15,-1"/>

            <Setter Property ="Template">
                <Setter.Value>
                    <ControlTemplate TargetType ="{x:Type TabItem }">
                        <Grid Height="32"  SnapsToDevicePixels="true">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="20"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <ZetaBase:SplineBorder
                                                x:Name="splineBd"
                                                Fill="{TemplateBinding Background}"
                                                Stroke="{TemplateBinding BorderBrush}"
                                                BottomBorderMargin="0.5"/>

                            <Border x:Name="Bd" Grid.Column="1"
                               BorderBrush="{TemplateBinding BorderBrush}"
                                           BorderThickness="0,1,1,0"
                                                    CornerRadius="0,2,0,0">
                                <Border  x:Name="BdInternal"
                               Background="{TemplateBinding Background}"
                               Padding="{TemplateBinding Padding}">
                                    <ContentPresenter    x:Name="Content"
                                ContentSource="Header"
                                                        HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                                                        VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                                                        RecognizesAccessKey="True"
                                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </Border>
                            </Border>
                            <!--
                                     This represents the Close-button.
                               
                                     The Command-binding that we create here refers to the Window's
                                     DataContext (which, for the sample, is the window's code-behind);
                                     In order for the Command to be able to determine which TabItem the
                                     button belongs to, a relative binding will do the trick (i.e.,
                                     (bubble up to the parent TabItem).Margin="-7,2,7,5" Content.DataContext-->

                            <Button x:Name="cmdTabItemCloseButton"
                                         Style="{StaticResource TabItemCloseButtonStyle}"
                                            VerticalAlignment="Top"
                                            HorizontalAlignment="Right"                                   
                                         Command="{Binding Path=CloseTabItemCommand}"
                                         CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TabItem}}}"
                                         Grid.Column="1"
                                            Visibility="Hidden"
                                            Margin="0,2,2,0"
                                        Padding="-1"                               
                                         />
                        </Grid >
                        <ControlTemplate.Triggers>
                            <DataTrigger Binding="{Binding Path=IsSelected}" Value="True">
                                <Setter Property="Visibility" Value="Visible" TargetName="cmdTabItemCloseButton"  />
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Path=IsActive}" Value="True">
                                <Setter Property="Visibility" Value="Visible" TargetName="cmdTabItemCloseButton"  />
                            </DataTrigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Visibility" Value="Visible" TargetName="cmdTabItemCloseButton"  />
                                <Setter Property="Margin" Value="2,1,-15,-1"/>
                            </Trigger>
                            <DataTrigger Binding="{Binding Path=CanClose}" Value="False">
                                <Setter Property="Visibility" Value="Collapsed" TargetName="cmdTabItemCloseButton"  />
                            </DataTrigger>
                             <Trigger Property="IsSelected"  Value="True">
                                <Setter Property="Panel.ZIndex" Value="100" />
                                <Setter Property="BorderBrush"      Value="{DynamicResource BaseColor5Key}" />
                                <Setter Property="Background"       Value="{DynamicResource BaseColor6Key}" />
                                <Setter Property="Margin" Value="-1,-1,-15,-1"/>
                                <Setter Property="Margin" TargetName="BdInternal" Value="0,0,0,-1"/>
                                <Setter Property="Margin" TargetName="splineBd" Value="0,0,0,-1.0"/>
                                <Setter Property="BottomBorderMargin" TargetName="splineBd" Value="1.5"/>
                                <Setter Property="FontWeight" Value="Bold"/>
                                <Setter Property="Visibility" Value="Visible" TargetName="cmdTabItemCloseButton"  />
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                    <Condition Property="IsSelected" Value="False"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="BorderBrush" Value="{DynamicResource BaseColor14Key}"/>
                                <Setter Property="Background" Value="{DynamicResource BaseColor17Key}"/>
                                <Setter Property="Panel.ZIndex" Value="0" />
                            </MultiTrigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="BorderBrush" Value="{DynamicResource BaseColor13Key}"/>
                                <Setter Property="Background" Value="{DynamicResource BaseColor9Key}"/>
                                <Setter Property="Foreground" Value="{DynamicResource GrayTextBrushKey}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>

                    </ControlTemplate >

                </Setter.Value >

            </Setter >

        </Style >

    2013年9月10日 9:05

答案

  • 您好,

    根据您提供的代码,我制作了简单的Demo进行测试,发现 样式“ZetaTabItemStyle” 中

    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>

    这个属性设置有问题,您这样的绑定可能导致了此TabItem无法被选中,UserControl的View就无法被正常显示。
    我按照您的第一段代码进行了修改:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
                //Zeta_tabWork 为TabControl ;CaseSheetView 为UserControl的View
                TabItem ti = new TabItem();
    
                Style tabStyle = (Style)this.FindResource("ZetaTabItemStyle");
                ti.Style = tabStyle;
    
                DataTemplate tabheaderStyle = (DataTemplate)this.FindResource("ZetaTabItemHeaderTemplate");
                ti.HeaderTemplate = tabheaderStyle;
    
                UserControl1 uc = new UserControl1();
                ti.Content = uc;
    
                ti.IsSelected = false;
                string sHeader = "新开案_1";
                ti.Width = 120;
                ti.Header = sHeader;
    
                int iindex = Zeta_tabWork.Items.Add(ti);
                Zeta_tabWork.SelectedItem = ti;
    
    }
    

    XAML中自己定义了DataTemplate "ZetaTabItemHeaderTemplate", 下图左侧为使用您的ZetaTabItemStyle后运行截图,右侧为注释那段代码(Property="IsSelected")后的显示效果:


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2013年9月11日 11:30
    版主

全部回复

  • 更正确的写法应该是这样的:

           private void CaseSheetNew_Click(object sender, RoutedEventArgs e)
            {
                //Zeta_tabWork 为TabControl ;CaseSheetView 为UserControl的View
                TabItem ti = new TabItem();

                CaseSheetView csv = new CaseSheetView();
                ti.Content = csv;
               
                ti.IsSelected = false;
                string sHeader = "新开案_1";
                ti.Width = 120;
                ti.Header = sHeader;
               
                int iindex = Zeta_tabWork.Items.Add(ti);

                DataTemplate tabheaderStyle = (DataTemplate)this.FindResource("ZetaTabItemHeaderTemplate");
                ti.HeaderTemplate = tabheaderStyle;

                Style tabStyle = (Style)this.FindResource("ZetaTabItemStyle");
                ti.Style = tabStyle;

                Zeta_tabWork.SelectedItem = ti;
         
            }

    原因:TabItem只有被加入到TabControl中,再应用样式或者模板才会正常起作用!!!!!!

    2013年9月10日 9:54
  • 您好,

    根据您提供的代码,我制作了简单的Demo进行测试,发现 样式“ZetaTabItemStyle” 中

    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>

    这个属性设置有问题,您这样的绑定可能导致了此TabItem无法被选中,UserControl的View就无法被正常显示。
    我按照您的第一段代码进行了修改:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
                //Zeta_tabWork 为TabControl ;CaseSheetView 为UserControl的View
                TabItem ti = new TabItem();
    
                Style tabStyle = (Style)this.FindResource("ZetaTabItemStyle");
                ti.Style = tabStyle;
    
                DataTemplate tabheaderStyle = (DataTemplate)this.FindResource("ZetaTabItemHeaderTemplate");
                ti.HeaderTemplate = tabheaderStyle;
    
                UserControl1 uc = new UserControl1();
                ti.Content = uc;
    
                ti.IsSelected = false;
                string sHeader = "新开案_1";
                ti.Width = 120;
                ti.Header = sHeader;
    
                int iindex = Zeta_tabWork.Items.Add(ti);
                Zeta_tabWork.SelectedItem = ti;
    
    }
    

    XAML中自己定义了DataTemplate "ZetaTabItemHeaderTemplate", 下图左侧为使用您的ZetaTabItemStyle后运行截图,右侧为注释那段代码(Property="IsSelected")后的显示效果:


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2013年9月11日 11:30
    版主