הצלחתי ב"ה
עריכה: הוספתי לו גם אפשרות להחליף מקומות של הטאבים:
<Window x:Class="wpflistview.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="500" Width="800"
>
<Window.Resources>
<!-- Style for the TabControl -->
<Style x:Key="TabControlStyle" TargetType="TabControl">
<Setter Property="AllowDrop" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabControl">
<Grid x:Name="TabcontrolMainGrid">
<Border x:Name="TabcontrolMainBorder2"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<Grid x:Name="TabcontrolMainGrid2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- ListBox for headers -->
<Grid x:Name="listBoxcontainerGrid" Grid.Row="0" Margin="0,0,0,-20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="TabHeaderListBox" Margin="0" Grid.Column="0" Padding="-2,-2,0,1"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
SelectionChanged="TabHeaderListBox_SelectionChanged"
ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Items}"
SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedItem}"
BorderBrush="{x:Null}" IsEnabled="True" Background="#FFFAFAFA">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border x:Name="TabItemBorder" BorderThickness="1" BorderBrush="{x:Null}"
Padding="5,2,5,2" Margin="-3,0,-3,0"
PreviewMouseMove="TabItemBorder_PreviewMouseMove"
DragOver="TabItemBorder_DragOver">
<Border.Effect>
<DropShadowEffect ShadowDepth="1" BlurRadius="1" Color="Black" Opacity="0.5"/>
</Border.Effect>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#F0F0F0"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="True">
<Setter Property="Background" Value="White"/>
</DataTrigger>
<!--<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="True">
<Setter Property="Background" Value="#40BFD4FF"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsMouseOff, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="True">
<Setter Property="Background" Value="#F0F0F0"/>
</DataTrigger>-->
</Style.Triggers>
</Style>
</Border.Style>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="tabItemTextBlock" Text="{Binding Header}" Margin="0,2,5,0"/>
<Button Content="X" x:Name="TabCloseButton"
Width="20"
Height="20"
Click="TabCloseButton_Click"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}, Path=DataContext.CloseTabCommand}"
CommandParameter="{Binding}" Background="{x:Null}" BorderBrush="{x:Null}" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<DockPanel HorizontalAlignment="Right" Background="#FFFAFAFA"
Margin="0,3,2,23" Height="23">
<Button x:Name="TabscrollLeft" Content="◁"
Click="TabscrollLeft_Click" Background="#F0F0F0"
BorderThickness="0" BorderBrush="{x:Null}" Margin="0,0,2,0">
<Button.Effect>
<DropShadowEffect ShadowDepth="1" BlurRadius="1" Color="Black" Opacity="0.5"/>
</Button.Effect>
</Button>
<Button x:Name="TabsDropDown" Content="▽"
Click="TabsDropDown_Click" Background="#F0F0F0"
BorderThickness="0" BorderBrush="{x:Null}" Margin="0,0,2,0">
<Button.Effect>
<DropShadowEffect ShadowDepth="1" BlurRadius="1" Color="Black" Opacity="0.5"/>
</Button.Effect>
<Button.ContextMenu>
<ContextMenu/>
</Button.ContextMenu>
</Button>
<Button x:Name="TabscrollRight" Content="▷"
Click="TabscrollRight_Click" Background="#F0F0F0"
BorderThickness="0" BorderBrush="{x:Null}">
<Button.Effect>
<DropShadowEffect ShadowDepth="1" BlurRadius="1" Color="Black" Opacity="0.5"/>
</Button.Effect>
</Button>
</DockPanel>
</Grid>
<!-- Content row -->
<Border Grid.Row="1" Height="0.5" Background="{TemplateBinding BorderBrush}"/>
<Border Grid.Row="2" x:Name="ContentPanel"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0.5"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ContentPresenter x:Name="PART_SelectedContentHost"
ContentSource="SelectedContent"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<!-- Apply the custom style to the TabControl -->
<TabControl Style="{StaticResource TabControlStyle}">
<!-- Add your tabs here -->
<TabItem Header="Tab 1">
<!-- Tab 1 content -->
</TabItem>
<TabItem Header="Tab 2">
<!-- Tab 2 content -->
</TabItem>
<!-- Add more tabs as needed -->
<TabItem Header="Tab 3">
asdfasdfasf
</TabItem>
<TabItem Header="Tab 4">
דכגשדגכשדכשדגכשדכג
</TabItem>
<!-- Add more tabs as needed -->
<TabItem Header="Tab 5">
<!-- Tab 1 content -->
</TabItem>
<TabItem Header="Tab 6">
<!-- Tab 2 content -->
</TabItem>
<!-- Add more tabs as needed -->
<TabItem Header="Tab 7">
<!-- Tab 1 content -->
</TabItem>
<TabItem Header="Tab 8">
<!-- Tab 2 content -->
</TabItem>
<!-- Add more tabs as needed -->
</TabControl>
</Grid>
</Window>
using BetterTabs;
using FirstFloor.ModernUI.Windows.Media;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace wpflistview
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void TabCloseButton_Click(object sender, RoutedEventArgs e)
{
// Handle the close button click event here
if (sender is Button closeButton && closeButton.DataContext is TabItem tabItem)
{
// Your custom logic to close the tab
// For example, remove the tab from the TabControl's Items collection
var tabControl = FindParent<TabControl>(closeButton);
(tabControl?.Items)?.Remove(tabItem);
}
}
private void TabscrollLeft_Click(object sender, RoutedEventArgs e)
{
var tabControl = FindParent<TabControl>(sender as DependencyObject);
if (tabControl != null)
{
int currentIndex = tabControl.SelectedIndex;
if (currentIndex > 0)
{
tabControl.SelectedIndex = currentIndex - 1;
}
}
}
private void TabsDropDown_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
ContextMenu contextMenu = new ContextMenu();
foreach (TabItem tabItem in ((TabControl)button.TemplatedParent).Items)
{
MenuItem menuItem = new MenuItem
{
Header = tabItem.Header,
Tag = tabItem
};
menuItem.Click += TabMenuItem_Click;
contextMenu.Items.Add(menuItem);
}
button.ContextMenu = contextMenu;
button.ContextMenu.IsOpen = true;
}
private void TabMenuItem_Click(object sender, RoutedEventArgs e) // Event handler for context menu item click
{
((ContextMenu)((MenuItem)sender).Parent).IsOpen = false; // Close the context menu
TabItem selectedTab = (TabItem)((MenuItem)sender).Tag; // Get the associated TabItem from the Tag property
((TabControl)selectedTab.Parent).SelectedItem = selectedTab; // Set the selected tab in the TabControl
}
private void TabscrollRight_Click(object sender, RoutedEventArgs e)
{
var tabControl = FindParent<TabControl>(sender as DependencyObject);
if (tabControl != null)
{
int currentIndex = tabControl.SelectedIndex;
if (currentIndex < tabControl.Items.Count - 1)
{
tabControl.SelectedIndex = currentIndex + 1;
}
}
}
private static T FindParent<T>(DependencyObject child) where T : DependencyObject
{
// Find the parent of a specified type in the visual tree
while (true)
{
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null)
{
return null;
}
if (parentObject is T parent)
{
return parent;
}
child = parentObject;
}
}
private void TabHeaderListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox listBox = (ListBox)sender;
if (listBox.SelectedItem != null)
{
listBox.ScrollIntoView(listBox.SelectedItem);
}
}
private static T FindAncestor<T>(DependencyObject current)
where T : DependencyObject
{
do
{
if (current is T ancestor)
{
return ancestor;
}
current = VisualTreeHelper.GetParent(current);
} while (current != null);
return null;
}
private void TabItemBorder_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (sender is Border border &&
border.DataContext is TabItem tabItem &&
Mouse.PrimaryDevice.LeftButton == MouseButtonState.Pressed)
{
DragDrop.DoDragDrop(tabItem, tabItem, DragDropEffects.All);
}
}
private void TabItemBorder_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetData(typeof(TabItem)) is TabItem tabItemSource &&
sender is Border border &&
border.DataContext is TabItem tabItemTarget &&
tabItemTarget.Parent is TabControl TergetTabControl)
{
int targetIndex = TergetTabControl.Items.IndexOf(tabItemTarget);
TabControl SourceControl = tabItemSource.Parent as TabControl;
SourceControl.Items.Remove(tabItemSource);
TergetTabControl.Items.Insert(targetIndex, tabItemSource);
tabItemSource.IsSelected = true;
}
}
}
}