fedeteka
fedeteka

Reputation: 963

Is there a way to set Font Dialog for show only a personalized set of fonts?

Creating a PDF with iTextSharp I need to let the user choose the fonts but with limitations about min and max size and also to a few list of fonts, maybe a list of fonts thay I will add to the resources folder of the program

Is there a way to set Font Dialog for show only a personalized set of fonts?, by example the ones on the myapppath/resources folder?

Dim myFont, mySize As String

Using dlg As New frmFonts

    dlg.FontMustExist = True

    dlg.MinSize = 9
    dlg.MaxSize = 14

    dlg.ShowEffects = False

    If dlg.ShowDialog <> DialogResult.Cancel Then
        myFont = dlg.Font.Name
        mySize = dlb.Font.Size
    End If

End Using

Attempted solution as suggested by @Tyler

Below is the code with automatic conversion from C# to VB.NET

I'm getting errors on the lines marked with **

error 1) Value of type 'FontListBox' cannot be converted to 'Control'

error 2) Conversions operators cannot convert from a type to the same type

Partial Public Class MyFontDialog
Inherits Form
Private _fontListBox As FontListBox
Private _fontSizeListBox As ListBox

Public Sub New()
    'InitializeComponent();

    _fontListBox = New FontListBox()
    AddHandler _fontListBox.SelectedIndexChanged, AddressOf OnfontListBoxSelectedIndexChanged
    _fontListBox.Size = New Size(200, Height)
    **Controls.Add(_fontListBox)**

    _fontSizeListBox = New ListBox()
    **_fontSizeListBox.Location = New Point(_fontListBox.Width, 0)**

    Controls.Add(_fontSizeListBox)
End Sub

Private Sub OnfontListBoxSelectedIndexChanged(sender As Object, e As EventArgs)
    _fontSizeListBox.Items.Clear()
    **Dim font As Font = TryCast(_fontListBox.SelectedItem, Font)**
    If font IsNot Nothing Then
        For Each style As FontStyle In [Enum].GetValues(GetType(FontStyle))
            If font.FontFamily.IsStyleAvailable(style) Then
                _fontSizeListBox.Items.Add(style)
            End If
        Next
    End If
End Sub
End Class

Friend Class FontListBox
    Friend Size As Size
    Public Event SelectedIndexChanged(sender As Object, e As EventArgs)

    **Public Shared Widening Operator CType(v As FontListBox) As FontListBox**
    Throw New NotImplementedException()
    End Operator
End Class

Upvotes: 2

Views: 1278

Answers (1)

Tyler
Tyler

Reputation: 426

I see that you have a custom control, so yes it is possible. Take a look here, for sure will help you Designing a Custom Font Dialog/Selector for C# that filters out non true type fonts

Edit:

In case the link will be broken, here is the part of code that you are interested for. Just change this IF If font.FontFamily.IsStyleAvailable(style) Then with your filtered FontName and you have done.

Private Sub OnfontListBoxSelectedIndexChanged(sender As Object, e As EventArgs)
_fontSizeListBox.Items.Clear()
Dim font As Font = TryCast(_fontListBox.SelectedItem, Font)
If font IsNot Nothing Then
    For Each style As FontStyle In [Enum].GetValues(GetType(FontStyle))
        If font.FontFamily.IsStyleAvailable(style) Then
            _fontSizeListBox.Items.Add(style)
        End If
    Next
End If
End Sub

EDIT2: Considerate your latest comment.. try to slit the 2 class in 2 vb files. Exactly like that:

Partial Public Class MyFontDialog
Inherits Form
Private _fontListBox As FontListBox
Private _fontSizeListBox As ListBox

Public Sub New()
    'InitializeComponent();

    _fontListBox = New FontListBox()
    AddHandler _fontListBox.SelectedIndexChanged, AddressOf OnfontListBoxSelectedIndexChanged
    _fontListBox.Size = New Size(200, Height)
    Controls.Add(_fontListBox)

    _fontSizeListBox = New ListBox()
    _fontSizeListBox.Location = New Point(_fontListBox.Width, 0)

    Controls.Add(_fontSizeListBox)
End Sub

Private Sub OnfontListBoxSelectedIndexChanged(sender As Object, e As EventArgs)
    _fontSizeListBox.Items.Clear()
    Dim font As Font = TryCast(_fontListBox.SelectedItem, Font)
    If Font IsNot Nothing Then
        For Each style As FontStyle In [Enum].GetValues(GetType(FontStyle))
            If Font.FontFamily.IsStyleAvailable(style) Then
                _fontSizeListBox.Items.Add(style)
            End If
        Next
    End If
End Sub
End Class

Second class:

Public Class FontListBox
Inherits ListBox
Private _fonts As New List(Of Font)()
Private _foreBrush As Brush

Public Sub New()
    DrawMode = DrawMode.OwnerDrawFixed
    ItemHeight = 20
    For Each ff As FontFamily In FontFamily.Families
        ' determine the first available style, as all fonts don't support all styles
        Dim availableStyle As System.Nullable(Of FontStyle) = Nothing
        For Each style As FontStyle In [Enum].GetValues(GetType(FontStyle))
            If ff.IsStyleAvailable(style) Then
                availableStyle = style
                Exit For
            End If
        Next

        If availableStyle.HasValue Then
            Dim font As Font = Nothing
            Try
                ' do your own Font initialization here
                ' discard the one you don't like :-)
                font = New Font(ff, 12, availableStyle.Value)
            Catch
            End Try
            If font IsNot Nothing Then
                _fonts.Add(font)
                Items.Add(font)
            End If
        End If
    Next
End Sub

Protected Overrides Sub Dispose(disposing As Boolean)
    MyBase.Dispose(disposing)
    If _fonts IsNot Nothing Then
        For Each font As Font In _fonts
            font.Dispose()
        Next
        _fonts = Nothing
    End If
    If _foreBrush IsNot Nothing Then
        _foreBrush.Dispose()
        _foreBrush = Nothing
    End If
End Sub

Public Overrides Property ForeColor() As Color
    Get
        Return MyBase.ForeColor
    End Get
    Set
        MyBase.ForeColor = Value
        If _foreBrush IsNot Nothing Then
            _foreBrush.Dispose()
        End If
        _foreBrush = Nothing
    End Set
End Property

Private ReadOnly Property ForeBrush() As Brush
    Get
        If _foreBrush Is Nothing Then
            _foreBrush = New SolidBrush(ForeColor)
        End If
        Return _foreBrush
    End Get
End Property

Protected Overrides Sub OnDrawItem(e As DrawItemEventArgs)
    MyBase.OnDrawItem(e)
    If e.Index < 0 Then
        Return
    End If

    e.DrawBackground()
    e.DrawFocusRectangle()
    Dim bounds As Rectangle = e.Bounds
    Dim font As Font = DirectCast(Items(e.Index), Font)
    e.Graphics.DrawString(font.Name, font, ForeBrush, bounds.Left, bounds.Top)
End Sub
End Class

Upvotes: 2

Related Questions