2011-01-28 8 views
4

タブコントロールを拡張して、タブアイテムを閉じることができます。Silverlight 4:閉じるタブアイテムの作成

私はケントのこのWPFのソリューションを発見した: On the WPF TabControl - can I add content next to the tab headers?

私はBlendで、既存のSilverlightのTabControlのコピーを開きました。しかし、構造はWPF tabcontrolとはかなり異なって見えます。私はそれをSilverlightコントロールテンプレートに直接取り込むことはできません。

誰も私のために良いリソースを知っていますか?

答えて

4

テンプレートTabItemには、現在選択されているタブを閉じるためのコードの後ろにフックアップできる何らかのクローズボタンがあります。

<Style TargetType="TabItem"> 
      <Setter.Value> 
       <ControlTemplate TargetType="sdk:TabItem"> 
          <Button x:Name="PART_btnClose" 
              Height="15" 
              Width="15" 
              Grid.Column="1" 
              HorizontalAlignment="Right" 
              VerticalAlignment="Center" 
              Margin="20,0,3,8" BorderThickness="1" Cursor="Hand" /> 
</ControlTemplate> 
</Setter.Value> 
</Style> 

この後、オン・アプリケーション・テンプレートで、ButtonClickedイベントをサブスクライブできます。このような

何か:その場合に

public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 

     PART_btnClose = GetTemplateChild("PART_btnClose") as Button; 

     if (PART_btnClose != null) 
     { 
      PART_btnClose.Click += new RoutedEventHandler(PART_btnClose_Click); 
     } 

、あなたのタブを閉じることができます。

希望これは、コードがそのまま動作しない可能性があります、すぐにそれをしました。

のTy Rozak

+0

あなたの答えをありがとう。これがどのように機能すべきかもう少し詳しく説明してください。 TabItemを拡張するTabItemExtクラスを作成すると、OnApplyTemplateをオーバーライドして、あなたが言ったことを行うことができます。しかし、私はまた、通常のTabItemの代わりにこの新しいTabItemExtを内部的に利用するTabControlExtをTabControlに拡張する必要があります。これはどうすればいいですか?多くのありがとう – Houman

+0

TabControlにビヘイビアを追加していない限り、CustomTabControlは必要ありません。普通のTabItemを追加するときにXamlまたはCodeBuilderに "CustomTabItem"を追加するだけです。これは、CustomTabItemがTabItemちょうど追加された振る舞いで。 –

5

私は前に同じ問題を抱えていた、そして私は、拡張TabControlを使用することにしました。私はどこでそれを見つけたのかわかりませんが、それは問題ではありません。今は私のプロジェクトです。

このTabControlを使用すると、ViewModelのコレクションから項目を追加または削除でき、変更がユーザーインターフェイスに反映されます。

MyTabControl.cs

public class MyTabControl : TabControl 
{ 
    public MyTabControl() 
     : base() 
    { 
     this.SelectionChanged += OnSelectionChanged; 
    } 

    #region Tabs with databinding and templates 
    /// <summary> 
    /// Template for a TabItem header 
    /// </summary> 
    public DataTemplate TabHeaderItemTemplate 
    { 
     get { return (DataTemplate)GetValue(TabHeaderItemTemplateProperty); } 
     set { SetValue(TabHeaderItemTemplateProperty, value); } 
    } 
    public static readonly DependencyProperty TabHeaderItemTemplateProperty = 
     DependencyProperty.Register("TabHeaderItemTemplate", typeof(DataTemplate), typeof(MyTabControl), new PropertyMetadata(
      (sender, e) => 
      { 
       ((MyTabControl)sender).InitTabs(); 
      })); 

    /// <summary> 
    /// Template for a content 
    /// </summary> 
    public DataTemplate TabItemTemplate 
    { 
     get { return (DataTemplate)GetValue(TabItemTemplateProperty); } 
     set { SetValue(TabItemTemplateProperty, value); } 
    } 
    public static readonly DependencyProperty TabItemTemplateProperty = 
     DependencyProperty.Register("TabItemTemplate", typeof(DataTemplate), typeof(MyTabControl), new PropertyMetadata(
      (sender, e) => 
      { 
       ((MyTabControl)sender).InitTabs(); 
      })); 

    /// <summary> 
    /// Source of clr-objects 
    /// </summary> 
    public IEnumerable MyItemsSource 
    { 
     get 
     { 
      return (IEnumerable)GetValue(MyItemsSourceProperty); 
     } 
     set 
     { 
      SetValue(MyItemsSourceProperty, value); 
     } 
    } 

    public static readonly DependencyProperty MyItemsSourceProperty = 
     DependencyProperty.Register("MyItemsSource", typeof(IEnumerable), typeof(MyTabControl), new PropertyMetadata(
      (sender, e) => 
      { 
       MyTabControl control = (MyTabControl)sender; 
       INotifyCollectionChanged incc = e.OldValue as INotifyCollectionChanged; 
       if (incc != null) 
       { 
        incc.CollectionChanged -= control.MyItemsSourceCollectionChanged; 
       } 
       control.InitTabs(); 

       incc = e.NewValue as INotifyCollectionChanged; 
       if (incc != null) 
       { 
        incc.CollectionChanged += control.MyItemsSourceCollectionChanged; 
       } 
      })); 


    /// <summary> 
    /// Selected item as object 
    /// </summary> 
    public object MySelectedItem 
    { 
     get { return (object)GetValue(MySelectedItemProperty); } 
     set { SetValue(MySelectedItemProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for MySelectedItem. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty MySelectedItemProperty = 
     DependencyProperty.Register("MySelectedItem", typeof(object), typeof(MyTabControl), new PropertyMetadata(
      (sender, e) => 
      { 
       MyTabControl control = (MyTabControl)sender; 

       if (e.NewValue == null) 
        control.SelectedItem = null; 
       else 
       { 
        var tab = control.Items.Cast<TabItem>().FirstOrDefault(ti => ti.DataContext == e.NewValue); 
        if (tab != null && control.SelectedItem != tab) 
         control.SelectedItem = tab; 
       } 
      })); 

    private void InitTabs() 
    { 
     Items.Clear(); 
     if (MyItemsSource != null && MyItemsSource.OfType<object>().Any()) 
     { 
      int i = 0; 
      foreach (var item in MyItemsSource) 
      { 
       var newitem = new TabItem(); 

       if (TabItemTemplate != null) 
        newitem.Content = TabItemTemplate.LoadContent(); 

       if (TabHeaderItemTemplate != null) 
        newitem.Header = TabHeaderItemTemplate.LoadContent(); 

       newitem.DataContext = item; 
       Items.Add(newitem); 
      } 
      VisualStateManager.GoToState(this, "Normal", true); 
     } 
     else VisualStateManager.GoToState(this, "NoTabs", true); 
    } 

    private void MyItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      if (e.NewStartingIndex > -1) 
      { 
       foreach (var item in e.NewItems) 
       { 
        var newitem = new TabItem(); 

        if (TabItemTemplate != null) 
         newitem.Content = TabItemTemplate.LoadContent(); 

        if (TabHeaderItemTemplate != null) 
         newitem.Header = TabHeaderItemTemplate.LoadContent(); 

        newitem.DataContext = item; 
        Items.Add(newitem); 
       } 
      } 
     } 
     else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove) 
     { 
      if (e.OldStartingIndex > -1) 
      { 
       var ti = (TabItem)this.Items[e.OldStartingIndex]; 
       Items.RemoveAt(e.OldStartingIndex); 
      } 
     } 
     else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace) 
     { 
      Items.RemoveAt(e.OldStartingIndex); 

      var newitem = new TabItem(); 

      if (TabItemTemplate != null) 
       newitem.Content = TabItemTemplate.LoadContent(); 

      if (TabHeaderItemTemplate != null) 
       newitem.Header = TabHeaderItemTemplate.LoadContent(); 

      newitem.DataContext = e.NewItems[0]; 

      Items.Add(newitem); 
      Items.Insert(e.NewStartingIndex, newitem); 
     } 
     else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset) 
     { 
      InitTabs(); 
     } 
    } 

    #endregion 

    private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     var si = e.AddedItems.Cast<TabItem>().FirstOrDefault(); 
     if (si != null) 
      this.MySelectedItem = si.DataContext; 
     else this.MySelectedItem = null; 
    } 
} 

MainPage.xamlを

<my:MyTabControl MyItemsSource="{Binding Items}" MySelectedItem="{Binding SelectedITem}"> 
     <my:MyTabControl.TabHeaderItemTemplate> 
      <DataTemplate> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="*"/> 
         <ColumnDefinition Width="Auto"/> 
        </Grid.ColumnDefinitions> 
        <TextBlock Text="{Binding Title}" VerticalAlignment="Center"/> 
        <Button Content="X" Margin="3" Width="20" Height="20" Grid.Column="1" 
          Command="{Binding RequestCloseCommand}"/> 
       </Grid> 
      </DataTemplate> 
     </my:MyTabControl.TabHeaderItemTemplate> 
     <my:MyTabControl.TabItemTemplate> 
      <DataTemplate> 
       <ContentControl Content="{Binding Content}"/> 
      </DataTemplate> 
     </my:MyTabControl.TabItemTemplate> 
    </my:MyTabControl> 

このTabControl使用オブジェクト、ないTabItemためのプロパティは、MyItemsSourceMySelectedItemと呼ばれていることに注意してください。

そして2のviewmodels: MainViewModel.cs

public class MainViewModel 
{ 
    public MainViewModel() 
    { 
     this.Items = new ObservableCollection<TabItemViewModel> 
         { 
          new TabItemViewModel("Tab 1", OnItemRequestClose), 
          new TabItemViewModel("Tab item 2", OnItemRequestClose) 
         }; 
    } 

    public ObservableCollection<TabItemViewModel> Items { get; set; } 

    public void OnItemRequestClose(TabItemViewModel item) 
    { 
     this.Items.Remove(item); 
    } 
} 

TabItemViewModel.cs

public class TabItemViewModel 
{ 
    public TabItemViewModel(string title, Action<TabItemViewModel> onClose) 
    { 
     this.Title = title; 
     this.RequestCloseCommand = new DelegateCommand(_ => onClose(this)); 

     //Just a demontration 
     this.Content = "Test content "+title; 
    } 

    public string Title { get; set; } 

    public ICommand RequestCloseCommand { get; set; } 

    public object Content { get; set; }  
} 
関連する問題