My Silverlight系列(5)—— Silverlight控件介绍之TabControl

TabControl这个控件想必大家都不陌生,无论是WinForm、Asp.net还是WPF中,这个通用控件都是非常有用的。

笔者最近在学习Silverlight中也应用到这个控件,发觉它与WPF中的TabControl是不尽相同的——这个事情让我非常的不解,主要是因为这个控件并不会涉及到安全因素,没有理由和WPF不一样(或许是我的类库版本有问题,也请大家有兴趣帮我验证一下)。

WPF的TabControl有ItemTemplate与ContentTemplate两个属性,前者可以为TabItem设置Header的模板,后者可以为TabItem设置Content模板。然而,在Silverlight的TabControl中,只有ItemTemplate这个属性(还有一个Template属性,但是一旦设置,就无法显示Header了)。于是退而求其次的,我只好为TabItem设置模板,幸运的是TabItem有HeaderTemplate与ContentTemplate两个属性,然而ContentTemplate并不Work,原因不明。。。

 

ContractedBlock.gif ExpandedBlockStart.gif Code
 1<UserControl xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Extended"  x:Class="SilverlightApplication1.Page"
 2    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
 3    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
 4    Width="800" Height="600">
 5    <Grid x:Name="LayoutRoot" Background="White">
 6        <Grid.RowDefinitions>
 7            <RowDefinition Height="30"/>
 8            <RowDefinition Height="*"/>
 9        </Grid.RowDefinitions>
10        <Button x:Name="myButton" Content="Click" Click="myButton_Click"/>
11        <my:TabControl x:Name="tab" Grid.Row="1">
12            <my:TabControl.Resources>
13                <Style x:Key="style" TargetType="my:TabItem">
14                    <!--Template for the headers (buttons)-->
15                    <Setter Property="HeaderTemplate">
16                        <Setter.Value>
17                            <DataTemplate>
18                                <Grid Margin="3">
19                                    <Grid.ColumnDefinitions>
20                                        <ColumnDefinition Width="*" />
21                                        <ColumnDefinition Width="Auto" />
22                                    </Grid.ColumnDefinitions>
23                                    <TextBlock Text="{Binding HeaderText}"
24                                               Grid.Column="0"
25                                               FontSize="11"
26                                               Margin="5 0 5 0"
27                                               VerticalAlignment="Center" />
28                                    <Button Content="x" Click="Button_Click"
29                                            FontSize="11"
30                                            VerticalAlignment="Center"
31                                            Grid.Column="1"
32                                            Width="16"
33                                            Height="16" Tag="{Binding}"/>
34                                </Grid>
35                            </DataTemplate>
36                        </Setter.Value>
37                    </Setter> 
38                    <!--Template for the content, however, it doesn't work-->
39                    <Setter Property="ContentTemplate">
40                        <Setter.Value>
41                            <DataTemplate>
42                                <Grid>
43                                    <TextBlock Text="{Binding ContentText}"/>
44                                </Grid>
45                            </DataTemplate>
46                        </Setter.Value>
47                    </Setter>
48                </Style>
49            </my:TabControl.Resources>
50        </my:TabControl>
51    </Grid>
52</UserControl>
53

后台代码:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Net;
 5using System.Windows;
 6using System.Windows.Controls;
 7using System.Windows.Documents;
 8using System.Windows.Input;
 9using System.Windows.Media;
10using System.Windows.Media.Animation;
11using System.Windows.Shapes;
12using System.Collections.ObjectModel;
13
14namespace SilverlightApplication1
15ExpandedBlockStart.gifContractedBlock.gif{
16    public partial class Page : UserControl
17ExpandedSubBlockStart.gifContractedSubBlock.gif    {
18        public Page()
19ExpandedSubBlockStart.gifContractedSubBlock.gif        {
20            InitializeComponent();
21            this.tab.ItemsSource = source;
22        }

23
24        private ObservableCollection<TabItem> source = new ObservableCollection<TabItem>();
25ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*
26         * 这是一种比较强悍的手段,在内部直接维护了一个Dicionary
27         * 当然也可以通过LINQ来查询source来找到相应的TabItem
28         * 这样做的目的是为了在点击Header的"x"时,可以关掉相应的Tab
29         */
 
30        private Dictionary<Data, TabItem> hash = new Dictionary<Data, TabItem>();
31        private void myButton_Click(object sender, RoutedEventArgs e)
32ExpandedSubBlockStart.gifContractedSubBlock.gif        {
33            TabItem tabItem = new TabItem();
34            Data data = new Data()
35ExpandedSubBlockStart.gifContractedSubBlock.gif            {
36                HeaderText = "myHeader",
37                ContentText = "abcd"
38            }
;
39            tabItem.Style = (Style)(this.tab.Resources["style"]);
40            tabItem.DataContext = data;
41            source.Add(tabItem);
42            hash[data] = tabItem;
43            tab.SelectedItem = tabItem;
44        }

45
46        private void Button_Click(object sender, RoutedEventArgs e)
47ExpandedSubBlockStart.gifContractedSubBlock.gif        {
48            var btn = sender as Button;
49            if (btn != null)
50ExpandedSubBlockStart.gifContractedSubBlock.gif            {
51                var data = btn.Tag as Data;
52                source.Remove(hash[data]);
53            }

54        }

55
56        public class Data
57ExpandedSubBlockStart.gifContractedSubBlock.gif        {
58ExpandedSubBlockStart.gifContractedSubBlock.gif            public string HeaderText getset; }
59ExpandedSubBlockStart.gifContractedSubBlock.gif            public string ContentText getset; }
60        }

61    }

62}

63

 

原本希望在Style中为TabItem设置它的HeaderTemplate与ContentTemplate,这样就可以在绑定DataContext的时候,对相应的控件属性进行绑定。然而运行的时候,可以发现ContentTemplate已经被赋值,但是却不会显示出来那个TextBlock。

 

至于上面这段代码最让我满意的,就是我为了TabItem的Header加入了一个Button,点击它的话,就可以将这个TabItem从TabControl中移除掉。

由于使用ContentTemplate的想法失败了,于是我只好动用TabItem的Content属性,代码做一下修改:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
 1        private void myButton_Click(object sender, RoutedEventArgs e)
 2ExpandedBlockStart.gifContractedBlock.gif        {
 3            TabItem tabItem = new TabItem();
 4            Data data = new Data()
 5ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 6                HeaderText = "myHeader",
 7                ContentText = "abcd"
 8            }
;
 9            tabItem.Style = (Style)(this.tab.Resources["style"]);
10            tabItem.DataContext = data;
11            Button button = new Button();
12            button.Content= data.ContentText;
13            tabItem.Content = button;
14            source.Add(tabItem);
15            hash[data] = tabItem;
16            tab.SelectedItem = tabItem;
17        }

这样就向TabItem的Content中加入了一人Button,Button的内容显示abcd。但是这样做有一个非常大的局限性,tabItem.Content属性虽然接受object类型,但是如果设置的不是ContentControl的子类,就会自动调用它的ToString()显示Content。于是这里有了一个权宜之计,就是加入一个Panel(如Canvas),这样向Pannel中就可以加入任何你想要的Control了。但是,我要说的是“但是”,这种方法无疑要求我们手写大量的cs代码而不是xaml代码,我认为这种方法是非常不好的。

我不知道我在设置TabItem的ContentTemplate的时候出了什么错,或者可以直接从TabControl的ItemTemplate(Template、ItemPanel等属性)中设置即可达到相应的效果,如果哪位做过类似的尝试或者有相关的资料可以告诉我,不胜感激。最后截一张运行时的效果图吧:

 

 

转载于:https://www.cnblogs.com/wodehuajianrui/archive/2008/08/06/1262214.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值