2011-12-27 18 views
8

由於內置字體對話框在選擇非真正類型字體時返回「不是真正類型字體」異常,我試圖創建一個自定義使用字體家族的字體對話框,用於過濾非真正的字體。爲C#設計一個自定義字體對話框/選擇器,用於過濾非真實類型字體

該控件工作完美,但我需要這個對話框的大小和樣式選擇器。我發佈了當前的代碼。請幫我添加一個大小和樣式選擇器。它也可能對你有用。

public class FontListBox : ListBox 
{ 
    private List<Font> _fonts = new List<Font>(); 
    private Brush _foreBrush; 

    public FontListBox() 
    { 
     DrawMode = DrawMode.OwnerDrawFixed; 
     ItemHeight = 20; 
     foreach (FontFamily ff in FontFamily.Families) 
     { 
      // determine the first available style, as all fonts don't support all styles 
      FontStyle? availableStyle = null; 
      foreach (FontStyle style in Enum.GetValues(typeof(FontStyle))) 
      { 
       if (ff.IsStyleAvailable(style)) 
       { 
        availableStyle = style; 
        break; 
       } 
      } 

      if (availableStyle.HasValue) 
      { 
       Font font = null; 
       try 
       { 
        // do your own Font initialization here 
        // discard the one you don't like :-) 
        font = new Font(ff, 12, availableStyle.Value); 
       } 
       catch 
       { 
       } 
       if (font != null) 
       { 
        _fonts.Add(font); 
        Items.Add(font); 
       } 
      } 
     } 
    } 

    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 
     if (_fonts != null) 
     { 
      foreach (Font font in _fonts) 
      { 
       font.Dispose(); 
      } 
      _fonts = null; 
     } 
     if (_foreBrush != null) 
     { 
      _foreBrush.Dispose(); 
      _foreBrush = null; 
     } 
    } 

    public override Color ForeColor 
    { 
     get 
     { 
      return base.ForeColor; 
     } 
     set 
     { 
      base.ForeColor = value; 
      if (_foreBrush != null) 
      { 
       _foreBrush.Dispose(); 
      } 
      _foreBrush = null; 
     } 
    } 

    private Brush ForeBrush 
    { 
     get 
     { 
      if (_foreBrush == null) 
      { 
       _foreBrush = new SolidBrush(ForeColor); 
      } 
      return _foreBrush; 
     } 
    } 

    protected override void OnDrawItem(DrawItemEventArgs e) 
    { 
     base.OnDrawItem(e); 
     if (e.Index < 0) 
      return; 

     e.DrawBackground(); 
     e.DrawFocusRectangle(); 
     Rectangle bounds = e.Bounds; 
     Font font = (Font)Items[e.Index]; 
     e.Graphics.DrawString(font.Name, font, ForeBrush, bounds.Left, bounds.Top); 
    } 
} 

public partial class MyFontDialog : Form 
{ 
    private FontListBox _fontListBox; 

    public MyFontDialog() 
    { 
     InitializeComponent(); 

     _fontListBox = new FontListBox(); 
     _fontListBox.Dock = DockStyle.Fill; 
     Controls.Add(_fontListBox); 
    } 
} 

我主持這個項目在SourceForge https://sourceforge.net/p/newfontpicker/

+0

FontDialog類已經過濾非TrueType字體。這裏真正的解決方案是卸載具有不良元數據的字體。 – 2011-12-29 15:13:40

+0

否。請參閱http://c-madeeasy.blogspot.com/2011/11/unsolved-this-is-not-true-type-font.html – techno 2011-12-29 15:15:08

+0

它試圖過濾掉這些opentype字體,但仍然存在一些字體。參見http://connect.microsoft.com/VisualStudio/feedback/details/708872/this-is-not-a-true-type-font-only-true-type-fonts-are-accepted-exception – techno 2011-12-29 15:16:18

回答

1

您可以修改MyFontDialog這樣的:

public partial class MyFontDialog : Form 
{ 
    private FontListBox _fontListBox; 
    private ListBox _fontSizeListBox; 

    public MyFontDialog() 
    { 
     //InitializeComponent(); 

     _fontListBox = new FontListBox(); 
     _fontListBox.SelectedIndexChanged += OnfontListBoxSelectedIndexChanged; 
     _fontListBox.Size = new Size(200, Height); 
     Controls.Add(_fontListBox); 

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

     Controls.Add(_fontSizeListBox); 
    } 

    private void OnfontListBoxSelectedIndexChanged(object sender, EventArgs e) 
    { 
     _fontSizeListBox.Items.Clear(); 
     Font font = _fontListBox.SelectedItem as Font; 
     if (font != null) 
     { 
      foreach (FontStyle style in Enum.GetValues(typeof(FontStyle))) 
      { 
       if (font.FontFamily.IsStyleAvailable(style)) 
       { 
        _fontSizeListBox.Items.Add(style); 
       } 
      } 
     } 
    } 
} 

這將創建一個列表框預留與可用字體樣式列表中的字體列表框中。至於尺寸選擇,您可以簡單地添加一個大小爲硬編碼列表的列表框:8,9,10,11,12,14,16,18,20,22,24,26,28,36,48和72 ,就像標準的FontDialog一樣,因爲我們正在處理真正的字體。

0

http://www.developerfusion.com/code/254/determine-if-a-font-is-truetype/有一些VB代碼,以確定字體是否是TT字體。它所做的只是調用一些Win32 API函數並檢查結果。

即使使用Win32 API(FontDialog可能會這樣做)進行檢查時,可能會出現一些TT字體,但不是。如果Win32沒有解決你的問題,那麼查找字體是否無效的唯一方法就是檢查是否有異常。

0

OK,歐麥爾, 你應該嘗試:

1)使用「FontFamily.IsStyleAvailable」,以避免/最小化需要捕獲異常 - ,從而錯過了一些可用的字體。 2)用一下Graphics.MeasureString設置大小爲每個單獨的字體看起來最好,將讓你的高度相等列...

快樂試圖:)

延,丹麥。