Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

Powershell GUI format text on TextBox and RichTextBox

I was preparing some auditing and reporting tools for some of newly received projects and wanted a way to formatting representation of data on my GUI form in nice way. To show this nice formatting you can use tags inside TextBlock and RichTextBox inside xaml code and binding can be used.These tags are as same as html tags. below examples are used on TextBlocks. For more on tagging you can check this link https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.documents.span, below are the few examples I used for formatting.

Sample text <Span FontWeight="Bold">bold</Span>, <Span FontStyle="Italic">italic</Span> and <Span TextDecorations="Underline">underlined</Span> words.
Text <Span Foreground="Blue">with blue </Span> <Span Foreground="Orange">and</Span> <Span Background="Magenta">Magenta highlight</Span> 

Microsoft Powershell wpf textbox richtext format text background foreground bold color underline italic text formatting run.png

Formatting text data on Richtextbox is very easy and formatting is done in same manner using tags on paragraphs in below format.

<Run FontFamily="Segoe UI" Text="This is "/>
<Run Foreground="#FFF00C0C" FontFamily="Segoe UI" Text="Line 1 "/>
<Run TextDecorations="Underline" FontStyle="Italic" FontFamily="Segoe UI" Text="Underline and Italic"/>

Download this script here, it is also available on github.com.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 <#  
   .NOTES  
   --------------------------------------------------------------------------------  
    Code generated using by: Visual Studio  
    Created on:              26 June 2018 4:57 AM  
    Get Help on:             http://vcloud-lab.com  
    Written by:              Kunal Udapi  
    Build & Tested on:       Windows 10  
    Purpose:                 This script is an example of styling Font on textbox.
   --------------------------------------------------------------------------------  
   .DESCRIPTION  
     GUI script generated using Visual Studio 2017  
 #>  

#Load required libraries 
Add-Type -AssemblyName PresentationFramework, PresentationCore, WindowsBase, System.Windows.Forms, System.Drawing  
[xml]$xaml = @" 
<Window 
        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"
        xmlns:local="clr-namespace:WpfApp9"
        
        Title="MainWindow" Height="315" Width="440">
    <Grid>
        <TextBox Name='StrComputerName' HorizontalAlignment="Left" Height="23" Margin="180,11,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="151"/>
        <WrapPanel HorizontalAlignment="Left" Height="32" Margin="10,39,0,0" VerticalAlignment="Top" Width="401">
            <TextBlock TextWrapping="Wrap" Text="ComputerName: " FontWeight="Bold" />
            <TextBlock FontStyle='Italic' Text="{Binding Path=Text, ElementName=StrComputerName}"/>
        </WrapPanel>

        <TextBlock HorizontalAlignment="Left" Margin="10,71,0,0" VerticalAlignment="Top" Width="401" Height="28" >
            <!-- Label control with <Bold>bold</Bold>, <Italic>italic</Italic> and <Underline>underlined</Underline> text -->
            Sample text <Span FontWeight="Bold">bold</Span>, <Span FontStyle="Italic">italic</Span> and <Span TextDecorations="Underline">underlined</Span> words.
        </TextBlock>

        <TextBlock HorizontalAlignment="Left" Margin="10,99,0,0" VerticalAlignment="Top" Width="401" Height="33" xml:space="preserve">
            Text <Span Foreground="Blue">with blue </Span> <Span Foreground="Orange">and</Span> <Span Background="Magenta">Magenta highlight</Span> <Span Foreground="Cyan">and Cyan color</Span>
        </TextBlock>

        <TextBlock HorizontalAlignment="Left" Height="53" Margin="10,132,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="401">
            <TextBlock.Inlines>
                <Run FontWeight="Bold" FontSize="14" Text="Bold TextBox Example. " />
                <Run FontStyle="Italic" Foreground="Red" Text="Red Text " />
                <LineBreak/> <!-- Next Line -->
                <Run TextDecorations="StrikeThrough" Text="StrikeThrough " />
            </TextBlock.Inlines>
        </TextBlock>

        <RichTextBox HorizontalAlignment="Left" Height="74" Margin="10,195,0,0" VerticalAlignment="Top" Width="401">
        <FlowDocument>
            <Paragraph>
                <Run FontFamily="Segoe UI" Text="This is "/>
                <Run Foreground="#FFF00C0C" FontFamily="Segoe UI" Text="Line 1 "/>
                <Run TextDecorations="Underline" FontStyle="Italic" FontFamily="Segoe UI" Text="Underline and Italic"/>
            </Paragraph>
            <Paragraph>
                <Run FontFamily="Segoe UI" Text="This is "/>
                <Run Foreground="#FF3E8B8B" FontFamily="Segoe UI" Text="Line 2 "/>
                <Run Background="LightSkyBlue" FontFamily="Segoe UI" Text="Different Background"/>
            </Paragraph>
        </FlowDocument>
        </RichTextBox>
    </Grid>
</Window>
"@ 

#Read the form 
$Reader = (New-Object System.Xml.XmlNodeReader $xaml)  
$Form = [Windows.Markup.XamlReader]::Load($reader)  

#AutoFind all controls 
$xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]")  | ForEach-Object {  
  New-Variable  -Name $_.Name -Value $Form.FindName($_.Name) -Force  
} 

#Mandetory last line of every script to load form 
[void]$Form.ShowDialog() 

The earlier shown tags example was to update XAML code directly, but I was also looking to update text after data collection, and my report should be looking nicer, cleaner and professional while sharing. As below I have 2 screenshots of same report but check the difference right side of screen definitely looks cool and much good in readable format, for example I need to highlight if there is a unwanted settings it should be shown as Red. 

Microsoft powershell wpf gui graphical user interface, forms Text formating textbox richtextbox controls, bold italic, backgroundproperty foregroundproperty, underlined strike, font size

Here in this script I have created two functions, first is for TextBox and second is for RichTextBox. The gist is as below.

First function TextFormatting has below code and it is to format text on Textblock. More information on this object can be found here https://msdn.microsoft.com/en-us/library/system.windows.documents.run(v=vs.110).aspx.

$ObjRun = New-Object System.Windows.Documents.Run
$ObjRun.FontWeight = 'Bold'
$ObjRun.Text = 'Your text'

$TextBlock.Inlines.Add($ObjRun)

Next function Format-RichTextBox formats text on richtextbox, more Information can be found on this .net object as below urls.
https://msdn.microsoft.com/en-us/library/system.windows.documents.textrange(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.windows.documents.textrange.applypropertyvalue(v=vs.110).aspx

$RichTextRange = New-Object System.Windows.Documents.TextRange($RichTextBoxControl.Document.ContentEnd, $RichTextBoxControl.Document.ContentEnd) #($RichTextBoxControl.Document.ContentStart, $RichTextBoxControl.Document.ContentEnd)
$RichTextRange.Text = 'YourText'
$RichTextRange.ApplyPropertyValue([System.Windows.Documents.TextElement]::BackgroundProperty, 'DarkGreen')

Download this script here, it is also available on github.com.

 <#   
   .NOTES   
   --------------------------------------------------------------------------------   
   Code generated using by: Visual Studio 2017  
   Created on:       26 June 2018 4:57 AM   
   Get Help on:       http://vcloud-lab.com   
   Written by:       Kunal Udapi   
   Build & Tested on:    Windows 10   
   Purpose:         This script is an example of styling Font on textbox.  
   Useful Article:     http://www.wpf-tutorial.com/basic-controls/the-textblock-control-inline-formatting/  
   --------------------------------------------------------------------------------   
   .DESCRIPTION   
    GUI script generated using Visual Studio 2017   
 #>   
   
 $Path = Split-Path -Parent $MyInvocation.MyCommand.Path  
 $ImgSrc = "$Path\BackGround.jpg"  
   
 #Load required libraries   
 Add-Type -AssemblyName PresentationFramework, PresentationCore, WindowsBase, System.Windows.Forms, System.Drawing  
 [xml]$xaml = @"  
 <Window  
     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"  
     xmlns:local="clr-namespace:WpfApp10"  
     Title="Server Audit" Height="390" Width="476" ResizeMode="NoResize" Topmost="True" WindowStartupLocation="CenterScreen">  
   
   <Grid>  
     <Image HorizontalAlignment="Left" Height="419" VerticalAlignment="Top" Width="469" Source="$ImgSrc"/>  
     <Label Name='Url' Content='http://vcloud-lab.com' HorizontalAlignment="Left" Margin="334,7,0,0" VerticalAlignment="Top" Foreground="LightGray" Cursor='Hand' ToolTip='http://vcloud-lab.com'/>  
     <TextBox Name='ComputerName' HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="$env:COMPUTERNAME" VerticalAlignment="Top" Width="177"/>  
     <Button Name='Audit' Content="Audit" HorizontalAlignment="Left" Margin="192,10,0,0" VerticalAlignment="Top" Height="23" Width="75"/>  
     <TextBlock Name='CompInfo' HorizontalAlignment="Left" Margin="10,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="449" Height="180"/>  
     <RichTextBox Name='AuditPart' HorizontalAlignment="Left" Height="110" Margin="10,230,0,0" VerticalAlignment="Top" Width="440">  
       <RichTextBox.Resources>  
         <Style TargetType="{x:Type Paragraph}">  
           <Setter Property="Margin" Value="0" />  
         </Style>  
       </RichTextBox.Resources>  
         <FlowDocument>  
           <Paragraph>  
             <!-- <Run Text="RichTextBox"/> -->  
           </Paragraph>  
         </FlowDocument>  
     </RichTextBox>  
   </Grid>  
 </Window>  
 "@   
   
 #Read the form   
 $Reader = (New-Object System.Xml.XmlNodeReader $xaml)   
 $Form = [Windows.Markup.XamlReader]::Load($reader)   
   
 #AutoFind all controls   
 $xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object {   
  New-Variable -Name $_.Name -Value $Form.FindName($_.Name) -Force   
 }  
   
 $AuditPart.IsReadOnly = $true  
 $Url.Add_MouseLeftButtonUp({[system.Diagnostics.Process]::start('http://www.google.com')})  
 $Url.Add_MouseEnter({$Url.Foreground = 'DarkGray'})  
 $Url.Add_MouseLeave({$Url.Foreground = 'LightGray'})  
   
 function TextFormatting {  
   [CmdletBinding(  
     ConfirmImpact='Medium',  
     HelpURI='http://vcloud-lab.com'  
   )]  
   Param (  
     [parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]  
     [String]$Text,  
     [Switch]$Bold, #https://docs.microsoft.com/en-us/uwp/api/windows.ui.text.fontweights  
     [Switch]$Italic, #https://docs.microsoft.com/en-us/uwp/api/windows.ui.text.fontstyle  
     [String]$TextDecorations, #https://docs.microsoft.com/en-us/uwp/api/windows.ui.text.textdecorations  
     [Int]$FontSize,  
     [String]$Foreground,  
     [String]$Background,  
     [Switch]$NewLine  
   )  
   Begin {  
     #https://docs.microsoft.com/en-us/uwp/api/windows.ui.text  
     $ObjRun = New-Object System.Windows.Documents.Run  
     function TextUIElement {  
       Param (  
           [parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]  
           [String]$PropertyName  
         )  
       $Script:PropValue = $PropertyName  
       Switch ($PropertyName) {  
         'Bold' {'FontWeight'} #Thin, SemiLight, SemiBold, Normal, Medium, Light, ExtraLight, ExtraBold, ExtraBlack, Bold, Black  
         'Italic' {'FontStyle'} #Italic, Normal, Oblique  
         'TextDecorations' {'TextDecorations'} #None, Strikethrough, Underline  
         'FontSize' {'FontSize'}  
         'Foreground' {'Foreground'}  
         'Background' {'Background'}  
         'NewLine' {'NewLine'}  
       }  
     }  
   }  
   Process {  
     if ($PSBoundParameters.ContainsKey('NewLine')) {  
       $ObjRun.Text = "`n$Text "  
     }  
     else {  
       $ObjRun.Text = $Text  
     }  
       
     $AllParameters = $PSBoundParameters.Keys | Where-Object {$_ -ne 'Text'}  
   
     foreach ($SelectedParam in $AllParameters) {  
       $Prop = TextUIElement -PropertyName $SelectedParam  
       if ($PSBoundParameters[$SelectedParam] -eq [System.Management.Automation.SwitchParameter]::Present) {  
         $ObjRun.$Prop = $PropValue  
       }  
       else {  
         $ObjRun.$Prop = $PSBoundParameters[$Prop]  
       }  
     }  
     $ObjRun  
   }  
 }  
 function Format-RichTextBox {  
   #https://msdn.microsoft.com/en-us/library/system.windows.documents.textelement(v=vs.110).aspx#Propertiesshut  
   param (  
     [parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]  
     [System.Windows.Controls.RichTextBox]$RichTextBoxControl,  
     [String]$Text,  
     [String]$ForeGroundColor = 'Black',  
     [String]$BackGroundColor = 'White',  
     [String]$FontSize = '12',  
     [String]$FontStyle = 'Normal',  
     [String]$FontWeight = 'Normal',  
     [Switch]$NewLine  
   )  
   $ParamOptions = $PSBoundParameters  
   $RichTextRange = New-Object System.Windows.Documents.TextRange(<#$RichTextBoxControl.Document.ContentStart#>$RichTextBoxControl.Document.ContentEnd, $RichTextBoxControl.Document.ContentEnd)  
   if ($ParamOptions.ContainsKey('NewLine')) {  
     $RichTextRange.Text = "`n$Text"  
   }  
   else {  
     $RichTextRange.Text = $Text  
   }  
   
   $Defaults = @{ForeGroundColor='Black';BackGroundColor='White';FontSize='12'; FontStyle='Normal'; FontWeight='Normal'}  
   foreach ($Key in $Defaults.Keys) {  
     if ($ParamOptions.Keys -notcontains $Key) {  
       $ParamOptions.Add($Key, $Defaults[$Key])  
     }  
   }   
   
   $AllParameters = $ParamOptions.Keys | Where-Object {@('RichTextBoxControl','Text','NewLine') -notcontains $_}  
   foreach ($SelectedParam in $AllParameters) {  
     if ($SelectedParam -eq 'ForeGroundColor') {$TextElement = [System.Windows.Documents.TextElement]::ForegroundProperty}  
     elseif ($SelectedParam -eq 'BackGroundColor') {$TextElement = [System.Windows.Documents.TextElement]::BackgroundProperty}  
     elseif ($SelectedParam -eq 'FontSize') {$TextElement = [System.Windows.Documents.TextElement]::FontSizeProperty}  
     elseif ($SelectedParam -eq 'FontStyle') {$TextElement = [System.Windows.Documents.TextElement]::FontStyleProperty}  
     elseif ($SelectedParam -eq 'FontWeight') {$TextElement = [System.Windows.Documents.TextElement]::FontWeightProperty}  
     $RichTextRange.ApplyPropertyValue($TextElement, $ParamOptions[$SelectedParam])  
   }  
 }  
   
 $Audit.Add_Click({  
   
   $CompInfo.Text = ''  
   $AuditPart.SelectAll()  
   $AuditPart.Selection.Text = ''  
   
   $OS = Get-WmiObject win32_OperatingSystem -ComputerName $ComputerName.Text  
   $Bios = Get-WmiObject win32_Bios -ComputerName $ComputerName.Text  
   $ComSys = Get-WmiObject win32_ComputerSystem -ComputerName $ComputerName.Text  
   $Patch = Get-HotFix -ComputerName $ComputerName.Text | Sort-Object -Property InstalledOn -Descending | Select-Object HotFixID, InstalledOn -First 1  
   $TimeZone = Get-WmiObject -Class win32_timezone -ComputerName $ComputerName.Text  
   
   #$CompInfo.Inlines.Add($(TextFormatting -Text 'OS Name: ' -Bold -FontSize 14 -Italic -TextDecorations Underline -Foreground DarkGreen -Background DarkRed))  
   $CompInfo.Inlines.Add($(TextFormatting -Text 'OS Name: ' -Bold -Italic))  
   $CompInfo.Inlines.Add("$($OS.Caption) `n")  
    
   $CompInfo.Inlines.Add($(TextFormatting -Text 'OS Version: ' -Bold))  
   $CompInfo.Inlines.Add("$($OS.Version) `n")   
   $CompInfo.Inlines.Add($(TextFormatting -Text 'OS Architecture: ' -Bold))  
   $CompInfo.Inlines.Add("$($OS.OSArchitecture) `n`n")  
   
   $CompInfo.Inlines.Add($(TextFormatting -Text 'Hardware Manufacturer: ' -Bold -FontSize 16))  
   $CompInfo.Inlines.Add("$($ComSys.Manufacturer) `n")  
   $CompInfo.Inlines.Add($(TextFormatting -Text 'Hardware Model: ' -Bold))  
   $CompInfo.Inlines.Add("$($ComSys.Model) `n")  
   $CompInfo.Inlines.Add($(TextFormatting -Text 'Sr. Number: ' -Bold))  
   $CompInfo.Inlines.Add("$($Bios.SerialNumber) `n")  
   $CompInfo.Inlines.Add($(TextFormatting -Text 'Bios Version: ' -Bold))  
   $CompInfo.Inlines.Add("$($Bios.Name) `n`n")   
     
   $CompInfo.Inlines.Add($(TextFormatting -Text 'Last patch and installed date: ' -Bold))  
   $CompInfo.Inlines.Add($(TextFormatting -Text $Patch.HotFixID -Italic -TextDecorations Underline -Foreground Blue -Bold))  
   $CompInfo.Inlines.Add(" - $($Patch.InstalledOn) `n")  
   
   $CompInfo.Inlines.Add($(TextFormatting -Text 'System TimeZone: ' -Bold))  
   if ($TimeZone.StandardName -eq 'India Standard Time') {  
     $CompInfo.Inlines.Add($(TextFormatting -Text $TimeZone.StandardName -Italic -Background DarkRed -Foreground White))  
   }  
   else {  
     $CompInfo.Inlines.Add($(TextFormatting -Text $TimeZone.StandardName -Italic -Foreground DarkGreen))  
   }  
   $CompInfo.Inlines.Add(' - Should be EST, CST or PST')  
     
   $CPU = Get-WmiObject win32_Processor -ComputerName $ComputerName.Text  
   $Service = Get-Service -Name WinRM, RemoteRegistry -ComputerName $ComputerName.Text   
   Format-RichTextBox -RichTextBoxControl $AuditPart -Text 'Processor: ' -FontWeight Bold -FontSize 18  
   Format-RichTextBox -RichTextBoxControl $AuditPart -Text $CPU.Name  
   Format-RichTextBox -RichTextBoxControl $AuditPart -Text 'Virtualization Enabled: ' -FontWeight Bold -NewLine  
   Format-RichTextBox -RichTextBoxControl $AuditPart -Text $CPU.VirtualizationFirmwareEnabled  
     
   $AuditPart.AppendText("`n")  
   Format-RichTextBox -RichTextBoxControl $AuditPart -Text 'Windows Remoting Service: ' -FontWeight Bold -NewLine  
   $Winrm = $Service | Where-Object {$_.Name -eq 'WinRM'}  
   if ($Winrm.Status -eq 'Running') {  
     Format-RichTextBox -RichTextBoxControl $AuditPart -Text $Winrm.Status -BackGroundColor LightGreen  
   }  
   elseif ($Winrm.Status -eq 'Stopped') {  
     Format-RichTextBox -RichTextBoxControl $AuditPart -Text $Winrm.Status -BackGroundColor DarkRed -ForeGroundColor White  
   }  
   else {  
     Format-RichTextBox -RichTextBoxControl $AuditPart -Text $Winrm.Status -BackGroundColor Yellow  
   }  
   Format-RichTextBox -RichTextBoxControl $AuditPart -Text ' - WinRM must be Running'  
     
   $RemoteRegistry = $Service | Where-Object {$_.Name -eq 'RemoteRegistry'}  
   Format-RichTextBox -RichTextBoxControl $AuditPart -Text 'Remote Registry Service: ' -FontWeight Bold -NewLine  
   if ($RemoteRegistry.Status -eq 'Running') {  
     Format-RichTextBox -RichTextBoxControl $AuditPart -Text $RemoteRegistry.Status -BackGroundColor DarkRed -ForeGroundColor White  
   }  
   else {  
     Format-RichTextBox -RichTextBoxControl $AuditPart -Text $RemoteRegistry.Status -BackGroundColor LightGreen  
   }  
   Format-RichTextBox -RichTextBoxControl $AuditPart -Text ' - Remove Registry must be stopped'  
   
 <#  
 $AuditPart.AppendText("New Text`n")  
 $AuditPart.Selection.Select($AuditPart.Selection.Start,$AuditPart.Selection.End)  
 $AuditPart.Selection.ApplyPropertyValue([System.Windows.Documents.TextElement]::ForegroundProperty,[System.Windows.Media.Brushes]::Red)  
 $AuditPart.AppendText("2nd Text`r")  
 $AuditPart.ScrollToEnd()  
 #>  
    
 })  
   
 #Mandetory last line of every script to load form   
 [void]$Form.ShowDialog()   
   

Useful Articles
Powershell GUI encode decode images
Powershell WPF Charts dashboard demo
Part 1: Create WPF XAML powershell GUI form with Visual studio
Part 2: Powershell and WPF: Build GUI applications tutorial
Part 3: Create shorter Microsoft Powershell WPF automated clean script
Powershell PoshGUI: Convert user to SID and vice versa using
Microsoft Powershell GUI: Change Internet Options connections Lan settings proxy server grayed out

Go Back

Comment

Blog Search

Page Views

11275732

Follow me on Blogarama