I have created an extended VB.NET version with additional features as requested in the comments to the original CodeProject article, Add/Remove Tabs Dynamically in WPF.
Introduction
This document and the demo are about an extended version of the 'Dynamic Tab' article.
Background
The CodeProject article "Add/Remove Tabs Dynamically in WPF" was my template for an extended VB.NET version with additional features as requested in the comments to the original article.
New Features
- Converted to VB.NET
- New
TabItem
header
styling based on an idea that was posted here - Loading a (rich) text file into
tab
- Loading a
UserControl
into tab
Ribbon
for menu items
The Ribbon
The Ribbon includes
Application
Menu
- QAT (
QuickAccessToolbar
) Ribbon
Tabs Start, Ribbon
Settings and Help
Version 1.2 or below: The Ribbon
works only for the top level tabcontrol
.
With C# version 1.3 the Ribbon
works for the top level tabcontrol
and for the usercontrol
.
With command Open, you can load a plain text file or a rich text file. The Tab
will show the file name after doing that.
The commands Search, Print and Info are only dummies without any function.
QAT (QuickAccessToolbar)
You can remove buttons from the QAT (on right click, a context menu appears for that).
And you can show QAT below the Ribbon
. You can Restore QAT from Settings Tab as well.
And you can change backcolor
of the Ribbon
.
Top Level tabcontrol
The basic features were already explained in the original article.
You can add a tabpage
with a click on the + button. The tabpage
content is a RichTextBox
.
Loading a (rich) text file into tab
with Ribbon Command
Load UC:
Private Sub Open_Click(sender As Object, e As RoutedEventArgs) Handles Open.Click,
AppCmdOpenQAT.Click, AppCmdOpen.Click
Add_TabItem(sender, Nothing)
tab.Header = io.OpenFileDlg(activeRTBox)
End Sub
Public Function OpenFileDlg(ByVal ActiveTBox As Object) As String
Dim dialog As FileDialog = New OpenFileDialog()
Try
dialog.Filter = "All Files(*.*)|*.*|RTF Files (*.rtf)|*.rtf"
dialog.FilterIndex = 1
dialog.Title = "RTE - Open File"
dialog.DefaultExt = "rtf"
dialog.ShowDialog()
If dialog.FileName = "" Then Exit Function
Dim strExt As String
strExt = System.IO.Path.GetExtension(dialog.FileName)
strExt = strExt.ToUpper()
If ActiveTBox.GetType.ToString = "System.Windows.Controls.RichTextBox" Then
Select Case strExt
Case ".RTF"
Dim t As New TextRange(ActiveTBox.Document.ContentStart,
ActiveTBox.Document.ContentEnd)
Dim file As New FileStream(dialog.FileName, FileMode.Open)
t.Load(file, System.Windows.DataFormats.Rtf)
file.Close()
Case Else
Dim t As New TextRange(ActiveTBox.Document.ContentStart,
ActiveTBox.Document.ContentEnd)
Dim file As New FileStream(dialog.FileName, FileMode.Open)
t.Load(file, System.Windows.DataFormats.Text)
file.Close()
End Select
Dim currentFile As String = dialog.FileName
dialog.Title = "Editor: " & currentFile.ToString()
Return dialog.SafeFileName
Else
If ActiveTBox.GetType.ToString = "System.Windows.Controls.TextBox" Then
Dim currentFile As String = dialog.FileName
ActiveTBox.Text = ReadTextLines(dialog.FileName)
Return dialog.SafeFileName
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Function
Public Function ReadTextLines(FileName As String) As String
Dim fi As New IO.FileInfo(FileName)
ReadTextLines = Nothing
Try
If fi.Length > 0 Then
Using sr As New StreamReader(FileName)
Dim line As String
line = sr.ReadToEnd()
line = line.Replace(" " & Environment.NewLine, Environment.NewLine)
line = line.Replace(" " & Chr(9), "")
line = line.Replace(Chr(10), "")
line = line.Replace(Chr(13), Environment.NewLine)
line = line.Replace(Environment.NewLine & Environment.NewLine &
Environment.NewLine, Environment.NewLine)
line = line.Trim
146639-VB-NET-remove-extra-blank-lines-from-file
line = line.Replace(Environment.NewLine & Environment.NewLine,
Environment.NewLine)
Return line
End Using
Else
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Function
UserControl - Concept and Code
The XAML content which shows the TabItem
header styling:
Loading the UC
This happens from the Ribbon
with Load UC (in Group View):
Private Sub LoadUCRibbonButton_Click(sender As Object, e As RoutedEventArgs)
Handles LoadUCRibbonButton.Click
Me.tabDynamic.DataContext = Nothing
Dim tab As TabItem = AddTabItemUC()
Me.tabDynamic.DataContext = CorrectTabHeaders(_tabItems)
Me.tabDynamic.SelectedItem = tab
RibbonWPF.IsEnabled = False
End Sub
Public Function AddTabItemUC() As TabItem
Dim count = _tabItems.Count
tab = New TabItem()
tab.Background = New SolidColorBrush(Colors.LightGoldenrodYellow)
tab.Header = String.Format("UserControl1 [Doc. {0}]", count)
tab.HeaderTemplate = TryCast(Me.tabDynamic.FindResource("TabHeader"),
DataTemplate)
AddHandler tab.MouseDoubleClick,
New MouseButtonEventHandler(AddressOf tab_MouseDoubleClick)
AddHandler tab.MouseLeftButtonUp,
New MouseButtonEventHandler(AddressOf tab_MouseDownClick)
Dim txt As UserControl1 = New UserControl1
txt.Name = "txt"
tab.Content = txt
tab.Name = txt.Name
_tabItems.Insert(count - 1, tab)
Return tab
End Function
You can add a tabpage with a click on + button. The tabpage
content is a RichTextBox
.
Conclusion
This is only a demo – it is not production ready. But I think it will allow you a variety of extensions.
Final Note
I am very interested in feedback of any kind - problems, suggestions and other.
Credits / Reference
History
- 2nd August, 2022 - Initial submission
- 4th August, 2022 - Replaced source files with new version 1.1
- 21st February, 2023 - Replaced source files with new version 1.2 - now with VB and C# versions
- 31th May, 2024 - With C# version 1.3 the
Ribbon
works for the top level tabcontrol
and for the usercontrol
.