silverlight中创建自定义的Tabcontrol控件

silverlight中创建自定义的Tabcontrol控件

silverlight的SDK中已经提供了一个Tabcontrol 控件,但是在实际开发中还有很多问题需要修改。

问题1:TabItem没有关闭按钮。

问题2:TabItem的数量太多导致宽度超出的时候会换行显示

所以我们需要创建一个自己的Tabcontrol控件,既然SDK中已经实现了大部分功能,我们就在它的基础上修改下就好。

   废话不多说,先看效果

 silverlight中创建自定义的Tabcontrol控件_第1张图片

 

 

根据Sdk里面的源码重新控件主要分为两部分,即TabItem部分和Tabcontrol部分。

 

下面是TabItem部分XAML的关键代码:

    <Grid x:Name="TemplateTopSelected" Visibility="Collapsed" Canvas.ZIndex="1">

                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" Background="{TemplateBinding Background}" Margin="-2,-2,-2,0" CornerRadius="3,3,0,0">

                                <Border BorderThickness="1" BorderBrush="#FFFFFFFF" CornerRadius="1,1,0,0">

                                    <Border.Background>

                                        <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">

                                            <GradientStop Color="#FFFFFFFF" Offset="0" />

                                            <GradientStop Color="#F9FFFFFF" Offset="0.375" />

                                            <GradientStop Color="#E5FFFFFF" Offset="0.625" />

                                            <GradientStop Color="#C6FFFFFF" Offset="1" />

                                        </LinearGradientBrush>

                                    </Border.Background>

                                    <Grid>

                                        <Rectangle Fill="#FFFFFFFF" Margin="0,0,0,-2" />

                                        <StackPanel Orientation="Horizontal">

                                            <ContentControl x:Name="HeaderTopSelected" VerticalAlignment="Center" IsTabStop="False" Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" Margin="{TemplateBinding Padding}" Cursor="{TemplateBinding Cursor}" />

                                            <Border VerticalAlignment="Center" HorizontalAlignment="Right">

                                                <Button Content="X" Width="18" Height="18" FontSize="12" Margin="3,0,0,0" Style="{StaticResource closeButtonStyle}" x:Name="Button1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Transparent">

                                                </Button>

                                            </Border>

                                        </StackPanel>

                                    </Grid>

                                </Border>

                            </Border>

                            <!--Focus Visual-->

                            <Border x:Name="FocusVisualTop" CornerRadius="3,3,0,0" BorderBrush="#FF6DBDD1" BorderThickness="1,1,1,0" Margin="-2,-2,-2,0" Visibility="Collapsed" IsHitTestVisible="false" />

                            <Border Margin="-2,-2,-2,0" x:Name="DisabledVisualTopSelected" IsHitTestVisible="false" Opacity="0" Background="#8CFFFFFF" CornerRadius="3,3,0,0" />

                        </Grid>

                        <!-- TabStripPlacement Top | Unselected -->

                        <Grid x:Name="TemplateTopUnselected" Visibility="Collapsed">

                            <Border x:Name="BorderTop" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" Background="{TemplateBinding Background}" CornerRadius="3,3,0,0">

                                <Border x:Name="GradientTop" BorderThickness="1" BorderBrush="#FFFFFFFF" CornerRadius="1,1,0,0">

                                    <Border.Background>

                                        <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">

                                            <GradientStop Color="#FFFFFFFF" Offset="0" />

                                            <GradientStop Color="#F9FFFFFF" Offset="0.375" />

                                            <GradientStop Color="#E5FFFFFF" Offset="0.625" />

                                            <GradientStop Color="#C6FFFFFF" Offset="1" />

                                        </LinearGradientBrush>

                                    </Border.Background>

                                    <Grid>

                                        <StackPanel Orientation="Horizontal">

                                            <ContentControl x:Name="HeaderTopUnselected" IsTabStop="False" Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" Margin="{TemplateBinding Padding}" Cursor="{TemplateBinding Cursor}" />

                                            <Border Height="18" Width="18" VerticalAlignment="Center" Margin="3,0,3,0" HorizontalAlignment="Right">

                                                <Button Content="X" Style="{StaticResource closeButtonStyle}" x:Name="Button2" VerticalAlignment="Stretch" Visibility="Collapsed" HorizontalAlignment="Stretch" Background="Transparent">

                                                </Button>

                                            </Border>

                                        </StackPanel>

                                    </Grid>

                                </Border>

                            </Border>

                            <Border x:Name="DisabledVisualTopUnSelected" IsHitTestVisible="false" Opacity="0" Background="#8CFFFFFF" CornerRadius="3,3,0,0" />

                        </Grid> 

 

 

下面是TabItem部分 CS 的代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

 

namespace Eos.EosControl

{

    [TemplatePart(Name = "Button1", Type = typeof(Button))]

    [TemplatePart(Name = "Button2", Type = typeof(Button))]

    public class EosTabItem : TabItem

    {

        private static Button CloseButton;

        private static Button CloseButton1;

 

        public EosTabItem()

        {

            this.DefaultStyleKey = typeof(EosTabItem);         

        }

 

        public override void OnApplyTemplate()

        {

            base.OnApplyTemplate();

            CloseButton = (GetTemplateChild("Button1") as Button);

            CloseButton1 = (GetTemplateChild("Button2") as Button);

            if (CloseButton != null && CloseButton1 != null)

            {

                CloseButton.Click += new RoutedEventHandler(CloseButton_Click);

                CloseButton1.Click += new RoutedEventHandler(CloseButton_Click);

                this.MouseEnter+=new MouseEventHandler(EosTabItem_MouseEnter);

                this.MouseLeave+=new MouseEventHandler(EosTabItem_MouseLeave);

            }

        }

 

        void CloseButton_Click(object sender, RoutedEventArgs e)

        {

            if (this.Parent as EosTabControl != null)

            {

                if ((this.Parent as EosTabControl).Items.Count > 1)

                {

                    (this.Parent as EosTabControl).Items.Remove(this);

                }

            }

            else if(this.Parent as TabControl!=null)

            {

                if ((this.Parent as TabControl).Items.Count > 1)

                {

                    (this.Parent as TabControl).Items.Remove(this);

                }

            }

        }

 

        void EosTabItem_MouseLeave(object sender, MouseEventArgs e)

        {

            CloseButton1 = (GetTemplateChild("Button2") as Button);

            CloseButton1.Visibility = Visibility.Collapsed;

        }

 

        void EosTabItem_MouseEnter(object sender, MouseEventArgs e)

        {

            CloseButton1 = (GetTemplateChild("Button2") as Button);

            CloseButton1.Visibility = Visibility.Visible;

        }

    }

}

 

 

 

 

下面是TabControl部分 XAML 的关键代码:

   <!-- TabStripPlacement Top -->

                        <Grid x:Name="TemplateTop" Visibility="Collapsed">

                            <Grid.RowDefinitions>

                                <RowDefinition Height="Auto" />

                                <RowDefinition Height="*" />

                            </Grid.RowDefinitions>

                            <Grid>

                                <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Canvas.ZIndex="1">

                                    <controlsPrimitives:TabPanel x:Name="TabPanelTop" Margin="2,2,2,-1">

                                    </controlsPrimitives:TabPanel>

                                </StackPanel>

                                <StackPanel VerticalAlignment="Bottom" >

                                    <Button x:Name="btnShowList" HorizontalAlignment="Right" Content="/EosControl;component/Images/ico1.jpg" Height="20">

                                        <Button.Template>

                                            <ControlTemplate TargetType="Button">

                                                <Image Source="{TemplateBinding Content}" x:Name="btnImg"></Image>

                                            </ControlTemplate>

                                        </Button.Template>

                                    </Button>

                                    <Popup Width="auto" Height="auto" x:Name="HeadList" IsOpen="False">

                                    </Popup>

                                </StackPanel>

                            </Grid>

                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Row="1" MinHeight="10" MinWidth="10" CornerRadius="0,0,3,3">

                                <ContentPresenter x:Name="ContentTop" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" Margin="{TemplateBinding Padding}" Cursor="{TemplateBinding Cursor}" />

                            </Border>

                            <Border x:Name="DisabledVisualTop" IsHitTestVisible="False" Opacity="0" Canvas.ZIndex="1" Background="#8CFFFFFF" Grid.RowSpan="2" CornerRadius="0,0,3,3" Grid.Row="1" />

                        </Grid> 

 

 

下面是TabControl部分 CS 的代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Windows.Controls.Primitives;

using System.Windows.Media.Imaging;

 

namespace Eos.EosControl

{

    [TemplatePart(Name = "btnShowList", Type = typeof(Button))]

    [TemplatePart(Name = "TabPanelTop", Type = typeof(TabPanel))]

    [TemplatePart(Name = "HeadList", Type = typeof(TabPanel))]

    public class EosTabControl : TabControl

    {

        private static Button btnShowList;

        private static TabPanel itemPanel;

        private static Popup HeadList;

 

        public EosTabControl()

        {

            this.DefaultStyleKey = typeof(EosTabControl);

        }

 

        public override void OnApplyTemplate()

        {

            base.OnApplyTemplate();

            btnShowList = (GetTemplateChild("btnShowList") as Button);

            itemPanel = (GetTemplateChild("TabPanelTop") as TabPanel);

            HeadList = (GetTemplateChild("HeadList") as Popup);

            btnShowList.Click += new RoutedEventHandler(btnShowList_Click);

            this.SizeChanged += new SizeChangedEventHandler(EosTabControl_SizeChanged);

            itemPanel.SizeChanged += new SizeChangedEventHandler(itemPanel_SizeChanged);

            btnShowList.LostFocus += new RoutedEventHandler(btnShowList_LostFocus);

            btnShowList.MouseEnter += new MouseEventHandler(btnShowList_MouseEnter);

            btnShowList.MouseLeave += new MouseEventHandler(btnShowList_MouseLeave);

            this.MouseLeftButtonDown += new MouseButtonEventHandler(EosTabControl_MouseLeftButtonDown);

        }

 

        void btnShowList_MouseLeave(object sender, MouseEventArgs e)

        {

            if (HeadList.IsOpen == false)

            {

                btnShowList.Content = "/EosControl;component/Images/ico1.jpg";

            }

        }

 

        void btnShowList_MouseEnter(object sender, MouseEventArgs e)

        {

            if (HeadList.IsOpen == false)

            {

                btnShowList.Content = "/EosControl;component/Images/ico3.jpg";

            }

        }

 

        void EosTabControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

        {

            (this.SelectedItem as TabItem).Focus();

        }

 

        void btnShowList_LostFocus(object sender, RoutedEventArgs e)

        {

            HeadList.IsOpen = false;

            btnShowList.Content = "/EosControl;component/Images/ico1.jpg";

        }

 

        void btnShowList_Click(object sender, RoutedEventArgs e)

        {

            if (HeadList.IsOpen == false)

            {

                double maxWidth = 0;

                ListBox headContent = new ListBox();

                headContent.BorderThickness = new Thickness(3);

                foreach (TabItem eosItem in itemPanel.Children)

                {

                    headContent.Items.Add(eosItem.Header);

                    if (eosItem.ActualWidth > maxWidth)

                    {

                        maxWidth = eosItem.ActualWidth;

                    }

                }

                headContent.SelectionChanged += new SelectionChangedEventHandler(headContent_SelectionChanged);

 

                HeadList.Child = headContent;

                HeadList.HorizontalOffset = this.ActualWidth - maxWidth + 24;

                HeadList.VerticalOffset = 0;

                HeadList.IsOpen = true;

                btnShowList.Content = "/EosControl;component/Images/ico2.jpg";

            }

            else

            {

                (this.SelectedItem as TabItem).Focus();

            }

        }

 

        void EosTabControl_SizeChanged(object sender, SizeChangedEventArgs e)

        {

            if (this.ActualWidth > 0)

            {

                double maxWidth = this.ActualWidth;

                double itemsWidth = 30;

                double itemMaxWidth = 0;

                foreach (TabItem eosItem in itemPanel.Children)

                {

                    itemsWidth += eosItem.ActualWidth;

                    if (eosItem.ActualWidth > itemMaxWidth)

                    {

                        itemMaxWidth = eosItem.ActualWidth;

                    }

                    if (itemsWidth < maxWidth)

                    {

                        eosItem.Visibility = Visibility.Visible;

                    }

                    else

                    {

                        eosItem.Visibility = Visibility.Collapsed;

                    }

                }

                if (itemPanel.Children[0].Visibility == Visibility.Collapsed)

                {

                    (itemPanel.Children[0] as TabItem).Width = maxWidth - 40;

                    itemPanel.Children[0].Visibility = Visibility.Visible;

                }

 

                HeadList.HorizontalOffset = this.ActualWidth - itemMaxWidth + 24;

            }

        }

 

        void itemPanel_SizeChanged(object sender, SizeChangedEventArgs e)

        {

            if (this.ActualWidth > 0)

            {

                double maxWidth = this.ActualWidth;

                double itemsWidth = 30;

                double itemMaxWidth = 0;

                foreach (TabItem eosItem in itemPanel.Children)

                {

                    itemsWidth += eosItem.ActualWidth;

                    if (eosItem.ActualWidth > itemMaxWidth)

                    {

                        itemMaxWidth = eosItem.ActualWidth;

                    }

                    if (itemsWidth < maxWidth)

                    {

                        eosItem.Visibility = Visibility.Visible;

                    }

                    else

                    {

                        eosItem.Visibility = Visibility.Collapsed;

                    }

                }

                if (itemPanel.Children[0].Visibility == Visibility.Collapsed)

                {

                    (itemPanel.Children[0] as TabItem).Width = maxWidth - 40;

                    itemPanel.Children[0].Visibility = Visibility.Visible;

                }

 

                HeadList.HorizontalOffset = this.ActualWidth - itemMaxWidth + 24;

            }

        }

 

        void headContent_SelectionChanged(object sender, SelectionChangedEventArgs e)

        {

            foreach (TabItem eosItem in itemPanel.Children)

            {

                if (this.Items.IndexOf(eosItem) == (sender as ListBox).SelectedIndex)

                {

                    if (eosItem.Visibility == Visibility.Collapsed)

                    {

                        eosItem.Visibility = Visibility.Visible;

                        this.Items.Remove(eosItem);

                        this.Items.Insert(0, eosItem);

                        this.SelectedIndex = 0;

                        break;

                    }

                    else

                    {

                        this.SelectedIndex = this.Items.IndexOf(eosItem);

                        break;

                    }

                }

            }

            HeadList.IsOpen = false;

            (this.SelectedItem as TabItem).Focus();

            this.UpdateLayout();

        }

    }

}

下面是关闭按钮样式 XAML:

<Style TargetType="Button" x:Key="closeButtonStyle">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="Button">

                    <Border x:Name="RootElement" BorderThickness="1">

                        <VisualStateManager.VisualStateGroups>

                            <VisualStateGroup x:Name="CommonStates">

                                <VisualState x:Name="Normal"/>

                                <VisualState x:Name="MouseOver">

                                    <Storyboard>

                                        <ColorAnimation Duration="0" Storyboard.TargetName="BorderBrush"

                                            Storyboard.TargetProperty="Color" To="#ccc" />

                                        <ColorAnimation Duration="0" Storyboard.TargetName="BorderBrush2"

                                            Storyboard.TargetProperty="Color" To="Black" />

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="Pressed" />

                            </VisualStateGroup>

                            <VisualStateGroup x:Name="FocusStates">

                                <VisualState x:Name="Focused">

                                </VisualState>

                                <VisualState x:Name="Unfocused">

                                </VisualState>

                            </VisualStateGroup>

                        </VisualStateManager.VisualStateGroups>

                        <Border.Background>

                            <SolidColorBrush x:Name="BorderBrush" Color="{TemplateBinding Background}"/>

                        </Border.Background>

                        <Border.BorderBrush>

                            <SolidColorBrush x:Name="BorderBrush2" Color="{TemplateBinding BorderBrush}"></SolidColorBrush>

                        </Border.BorderBrush>

                        <Grid Background="{TemplateBinding Background}">

                            <ContentPresenter

                            Content="{TemplateBinding Content}"

                            ContentTemplate="{TemplateBinding ContentTemplate}"

                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"

                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />

                        </Grid>

                    </Border>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

 

此段代码还有不完善的地方,希望高手指点下。

 

 

源码下载 

你可能感兴趣的:(silverlight中创建自定义的Tabcontrol控件)