zoukankan      html  css  js  c++  java
  • silverlight中创建自定义的Tabcontrol控件

    silverlight中创建自定义的Tabcontrol控件

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

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

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

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

       废话不多说,先看效果

     

     

     

    根据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>

     

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

     

     

    源码下载 

  • 相关阅读:
    事件的解除与绑定
    JavaScript 继承
    left 和 margin-left
    表格 DOM 操作
    基于继承的拖拽
    碰撞运动
    弹性运动
    完美运动框架
    JS 操作 Cookie
    DIV拖拽
  • 原文地址:https://www.cnblogs.com/KennyGuo/p/1875297.html
Copyright © 2011-2022 走看看