簡體   English   中英

Combobox 如何設置 selectedValue

[英]Combobox how to set selectedValue

我有一個 combobox 我在里面填充字體。 我用來這樣做的方法在這個鏈接中。 我將在這里分享該問題的答案。

public YourForm()
{
    InitializeComponent();

    ComboBoxFonts.DrawItem += ComboBoxFonts_DrawItem;           
    ComboBoxFonts.DataSource = System.Drawing.FontFamily.Families.ToList();
}

private void ComboBoxFonts_DrawItem(object sender, DrawItemEventArgs e)
{
    var comboBox = (ComboBox)sender;
    var fontFamily = (FontFamily)comboBox.Items[e.Index];
    var font = new Font(fontFamily, comboBox.Font.SizeInPoints);

    e.DrawBackground();
    e.Graphics.DrawString(font.Name, font, Brushes.Black, e.Bounds.X, e.Bounds.Y);
}

現在我只對此代碼進行了 1 處更改,就是這樣:

cmbFonts.DrawMode = DrawMode.OwnerDrawFixed;

加載 fonts 沒有問題,它正在工作,但我嘗試在我的表單加載時設置 selectedvalue。 例如,我嘗試設置名為“arial”的字體。 為了做到這一點,我使用這個:

var dataSource = cmbFonts.DataSource as List<FontFamily>;
int res = -1;
try
{
  res = dataSource.IndexOf(new FontFamily(StaticVariables.FontName));
}
catch { }
if (res != -1)
  cmbFonts.SelectedIndex = res;

現在,當我這樣做時,我得到System.ArgumentOutOfRangeException錯誤,因為我沒有向Combobox添加任何項目我綁定了一個DataSource ,因此當我嘗試設置SelectedIndex時,我得到了這個錯誤,我知道,我也試過這個:

cmbFonts.SelectedValue = StaticVariables.FontName;

但是當我在 Visual Studio 中運行帶有斷點的代碼時,我發現我的SelectedValue永遠不會改變。 在執行該行之前,我看到 null 並且在執行之后我仍然在SelectedValue中看到 null ,我檢查了我的 StaticVariables.FontName 變量,字體顯示在其中。

我也嘗試過使用combobox.Text屬性,但沒有運氣,就像SelectedValue一樣,之前是空字符串,在我用斷點跳過它之后仍然相同。

TL;DR:我嘗試在 combobox 中填寫 select 表單加載項,其中我填充了DataSource

Here's a custom owner-drawn ComboBox class (here, named FontListCombo ) that shows compatible System Font Families, representing each ComboBox Item using the FontFamily name as the Item Text and the corresponding Font to draw the Item's text (a classic ComboBox Font selector, in實踐)。

自定義控件在運行時自動填充系統中可用的 Fonts 列表。 它還響應WM_FONTCHANGE消息(系統字體池更改時廣播;例如,在Fonts文件夾中添加或刪除字體),以更新字體列表並反映更改(也避免嘗試使用已經不存在了)。

ComboBox 項目的文本是使用TextRenderer.DrawText()而不是Graphics.DrawString()繪制的,因為前者在這種情況下會產生更清晰的結果。

The ComboBox.Items collection is represented by a collection of FontObject class objects, a public class that stores some of the properties of each FontFamily and also exposes a couple of static methods used internally to return a Font object or a FontFamily object, calling the corresponding自定義 ComboBox 的公共方法:

  • GetSelectedFont(SizeInPoints, FontStyle)方法從當前ComboBox.SelectedItem
  • GetSelectedFontFamily()從當前ComboBox.SelectedItem

它還覆蓋ToString() ,以返回其屬性值的摘要。

這種 object 容器更適合這里:將 FontFamily object 存儲為 ConboBox 項肯定會產生不同類型的問題,最明顯和最可悲的是,某些 FontFamily 對象會隨着時間的推移甚至在它們被刪除后立即失效存儲。 這些對象一開始並不意味着永久存儲,所以這並不奇怪。

如示例所示,從ComboBox.SelecteItem中獲取當前的 Font 和 FontFamily :
(這里, ComboBox 實例被命名為cboFontList

private void cboFontList_SelectionChangeCommitted(object sender, EventArgs e)
{
    Font font = cboFontList.GetSelectedFont(this.Font.SizeInPoints, FontStyle.Regular);
    FontFamily family = cboFontList.GetSelectedFontFamily();
    string fontDetails = (cboFontList.SelectedItem as FontListCombo.FontObject).ToString();
}

FontObject class 存儲了 FontFamily 的一些重要細節,例如Cell AscentCell DescentEM SizeLine Spacing
此處描述了有關如何使用這些功能的一些詳細信息:

使用圖形路徑正確繪制文本
Fonts 和文本指標

這是它的工作原理:

自定義組合框字體選擇器


FontListCombo 自定義控件:

using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

[DesignerCategory("Code")]
public class FontListCombo : ComboBox
{
    private List<FontObject> fontList = null;

    public FontListCombo() {
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.DrawMode = DrawMode.OwnerDrawVariable;
    }

    protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        if (!DesignMode) GetFontFamilies();
    }

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        if ((Items.Count == 0) || e.Index < 0) return;
        e.DrawBackground();
        var flags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter;
        using (var family = new FontFamily(this.GetItemText(Items[e.Index])))
        using (var font = new Font(family, 10F, FontStyle.Regular, GraphicsUnit.Point)) {
            TextRenderer.DrawText(e.Graphics, family.Name, font, e.Bounds, this.ForeColor, flags);
        }
        e.DrawFocusRectangle();
        base.OnDrawItem(e);
    }

    protected override void OnMeasureItem(MeasureItemEventArgs e) {
        base.OnMeasureItem(e);
        e.ItemHeight = this.Font.Height + 4;
    }

    private void GetFontFamilies()
    {
        this.fontList = new List<FontObject>();

        fontList.AddRange(FontFamily.Families
            .Where(f => f.IsStyleAvailable(FontStyle.Regular))
            .Select(f => new FontObject(f)).ToArray());
        this.DisplayMember = "FamilyName";
        this.ValueMember = "EmHeight";
        this.DataSource = fontList;
    }

    public FontFamily GetSelectedFontFamily()
    {
        if (this.SelectedIndex < 0) return null;
        return FontObject.GetSelectedFontFamily((FontObject)this.SelectedItem);
    }

    public Font GetSelectedFont(float sizeInPoints, FontStyle style)
    {
        if (this.SelectedIndex < 0) return null;
        return FontObject.GetSelectedFont((FontObject)this.SelectedItem, sizeInPoints, style);
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        switch (m.Msg) {
            case WM_FONTCHANGE:  // The System Font pool has changed
                GetFontFamilies();
                break;
        }
    }

    public class FontObject
    {
        public FontObject(FontFamily family) { GetFontFamilyInfo(family); }
        public string FamilyName { get; set; }
        public int EmHeight { get; set; }
        public int CellAscent { get; set; }
        public int CellDescent { get; set; }
        public int LineSpacing { get; set; }

        private void GetFontFamilyInfo(FontFamily family)
        {
            this.FamilyName = family.Name;
            this.EmHeight = family.GetEmHeight(FontStyle.Regular);
            this.CellAscent = family.GetCellAscent(FontStyle.Regular);
            this.CellDescent = family.GetCellDescent(FontStyle.Regular);
            this.LineSpacing = family.GetLineSpacing(FontStyle.Regular);
        }
        internal static FontFamily GetSelectedFontFamily(FontObject fobj) 
            => new FontFamily(fobj.FamilyName);

        internal static Font GetSelectedFont(FontObject fobj, float sizeInPoints, FontStyle style) 
            => new Font(GetSelectedFontFamily(fobj), sizeInPoints, style);

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.AppendLine(this.FamilyName);
            sb.AppendLine($"Em Height: {this.EmHeight}");
            sb.AppendLine($"Cell Ascent: {this.CellAscent}");
            sb.AppendLine($"Cell Descent: {this.CellDescent}");
            sb.AppendLine($"Line Spacing: {this.LineSpacing}");
            return sb.ToString();
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM