Click here to Skip to main content
15,867,835 members
Home / Discussions / C#
   

C#

 
AnswerRe: Virtual USB Com port makes my C# control application freeze and crash when I single-step the microcontroller with the USB-device Pin
Gerry Schmitz14-Jan-23 5:37
mveGerry Schmitz14-Jan-23 5:37 
SuggestionC# web page interaction Pin
Samar Shehzad12-Jan-23 18:48
Samar Shehzad12-Jan-23 18:48 
GeneralRe: C# web page interaction Pin
OriginalGriff12-Jan-23 18:56
mveOriginalGriff12-Jan-23 18:56 
GeneralRe: C# web page interaction Pin
Samar Shehzad12-Jan-23 18:58
Samar Shehzad12-Jan-23 18:58 
GeneralRe: C# web page interaction Pin
OriginalGriff12-Jan-23 19:26
mveOriginalGriff12-Jan-23 19:26 
GeneralRe: C# web page interaction Pin
Graeme_Grant12-Jan-23 19:59
mvaGraeme_Grant12-Jan-23 19:59 
AnswerRe: C# web page interaction Pin
Richard Deeming12-Jan-23 22:11
mveRichard Deeming12-Jan-23 22:11 
QuestionWhy isn't my semi-editable ComboBox drawing the text in gray when the dropdown list isn't showing? Pin
arnold_w10-Jan-23 2:25
arnold_w10-Jan-23 2:25 
I work with many Com-ports and to make them easier to keep track of I've created a combobox that has a fixed prefix (the information from the Device Manager, e.g. "STMicroelectronics STLink Virtual COM Port (COM21)") and an editable suffix where I can type in e.g. "My Product A". The code works great, but now I would like to also be able to disable (make the text gray) items in my combobox and it works fine in the dropdown list, but as soon as I close the dropdown list and only the selected item is shown, then the text is always enabled (black, not gray). Does anybody know what I should correct in my code to get the desired behavior?

C#
partial class SemiEditableComboBox
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.comboBox = new System.Windows.Forms.ComboBox();
        this.SuspendLayout();
        //
        // comboBox
        //
        this.comboBox.FormattingEnabled = true;
        this.comboBox.Location = new System.Drawing.Point(0, 0);
        this.comboBox.Name = "comboBox";
        this.comboBox.Size = new System.Drawing.Size(454, 24);
        this.comboBox.TabIndex = 0;
        //
        // SemiEditableComboBox
        //
        this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.Controls.Add(this.comboBox);
        this.Name = "SemiEditableComboBox";
        this.Size = new System.Drawing.Size(454, 24);
        this.ResumeLayout(false);

    }

    #endregion

    private System.Windows.Forms.ComboBox comboBox;
}


C#
public delegate void DelegateItemAndString(object item, string newString);

class SemiEditableComboBoxItem
{
    public string lastString;
    public string fixedPrefix;
    public DelegateItemAndString editableSuffixChanged;
    public bool enabled;

    public SemiEditableComboBoxItem(string lastString, string fixedPrefix, DelegateItemAndString editableSuffixChanged, bool enabled)
    {
        this.lastString = lastString;
        this.fixedPrefix = fixedPrefix;
        this.editableSuffixChanged = editableSuffixChanged;
        this.enabled = enabled;
    }
}

public partial class SemiEditableComboBox : UserControl
{
    private volatile bool modifySelection = false;
    private int currentlySelectedIndex;
    private List<SemiEditableComboBoxItem> items;
    public event EventHandler SelectedIndexChanged;

    public SemiEditableComboBox()
    {
        // Make the GUI independent of the DPI setting
        Font = new Font(Font.Name, 8.25f * 96f / CreateGraphics().DpiX, Font.Style, Font.Unit, Font.GdiCharSet, Font.GdiVerticalFont);
        InitializeComponent();
        this.comboBox.Width = this.Width;
        this.comboBox.Height = this.Height;
        items = new List<SemiEditableComboBoxItem>();
        this.Resize += new EventHandler(delegate(object sender, EventArgs e)
        {
            this.comboBox.Width = this.Width;
            this.comboBox.Height = this.Height;
        });
        this.comboBox.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);
        this.comboBox.TextChanged += new EventHandler(comboBox_TextChanged);
        this.comboBox.DrawMode = DrawMode.OwnerDrawFixed;
        this.comboBox.DrawItem += comboBox_DrawItem;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (modifySelection)
        {
            modifySelection = false;
            if ((comboBox != null) && (currentlySelectedIndex < items.Count) &&
                (items[currentlySelectedIndex] != null) &&
                (!string.IsNullOrEmpty(items[currentlySelectedIndex].fixedPrefix)))
            {
                comboBox.SelectionStart = items[currentlySelectedIndex].fixedPrefix.Length;  // Only select the editable portion of the text
                comboBox.SelectionLength = 200;                                              // Let's assume the editable portion is never greater than 200 characters
            }
        }
    }

    private void comboBox_DrawItem(object sender, DrawItemEventArgs ea)
    {
        ea.DrawBackground();
        ea.DrawFocusRectangle();

        Rectangle bounds = ea.Bounds;
        bool enableItem = (ea.Index < 0) ? false : ((SemiEditableComboBoxItem)items[ea.Index]).enabled;

        Font myFont = new Font(ea.Font, FontStyle.Italic);
        if (ea.Index != -1)
        {
            ea.Graphics.DrawString(comboBox.Items[ea.Index].ToString(), ea.Font, new SolidBrush(enableItem ? Color.Black : Color.Gray), bounds.Left, bounds.Top);
        }
        else
        {
            ea.Graphics.DrawString(Text, ea.Font, new SolidBrush(Color.Gray), bounds.Left, bounds.Top);
        }
    }

    private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
    {
        currentlySelectedIndex = this.comboBox.SelectedIndex;
        if (SelectedIndexChanged != null)
        {
            SelectedIndexChanged(sender, e);
        }
        modifySelection = true;
        this.Invalidate();
    }

    private void comboBox_TextChanged(object sender, EventArgs e)
    {
        int selectedIndex = comboBox.SelectedIndex;  // When we edit the currently shown text, then comboBox.SelectedIndex becomes -1!
        if (0 <= selectedIndex)
        {
            currentlySelectedIndex = selectedIndex;
        }

        if (items[currentlySelectedIndex].editableSuffixChanged == null)
        {  // There is no editable suffix for this item. Therefore, don't let the user change it
            this.comboBox.TextChanged -= new EventHandler(comboBox_TextChanged);
            comboBox.Text = items[currentlySelectedIndex].lastString;
            this.comboBox.TextChanged += new EventHandler(comboBox_TextChanged);
            return;
        }
        else if (this.comboBox.Text.StartsWith(items[currentlySelectedIndex].fixedPrefix))
        {
            items[currentlySelectedIndex].lastString = comboBox.Text;
        }
        else
        {   // Don't let the user delete the fixed prefix. Put the last string back again
            this.comboBox.TextChanged -= new EventHandler(comboBox_TextChanged);
            comboBox.Text = items[currentlySelectedIndex].lastString;
            this.comboBox.TextChanged += new EventHandler(comboBox_TextChanged);
        }
        if (!this.comboBox.Items[currentlySelectedIndex].ToString().Equals(items[currentlySelectedIndex].lastString))
        {
            this.comboBox.TextChanged -= new EventHandler(comboBox_TextChanged);
            this.comboBox.DrawMode = DrawMode.OwnerDrawFixed;  // Need to do this to update text in the combobox

            if (items[currentlySelectedIndex].editableSuffixChanged != null)
            {
                items[currentlySelectedIndex].editableSuffixChanged(comboBox.Items[currentlySelectedIndex], items[currentlySelectedIndex].lastString.Substring(items[currentlySelectedIndex].fixedPrefix.Length));
            }
            this.comboBox.DrawMode = DrawMode.Normal;          // Need to do this to update text in the combobox
            this.comboBox.DrawMode = DrawMode.OwnerDrawFixed;  // Need to do this to update text in the combobox
            this.comboBox.TextChanged += new EventHandler(comboBox_TextChanged);
        }
        comboBox.SelectionStart = items[currentlySelectedIndex].lastString.Length;
        comboBox.SelectionLength = 0;
    }

    public void addItem(object item, string initialText, string fixedPrefix, DelegateItemAndString editableSuffixChanged)
    {
        addItem(item, initialText, fixedPrefix, editableSuffixChanged, false);
    }

    public void addItem(object item, string initialText, string fixedPrefix, DelegateItemAndString editableSuffixChanged, bool enabled)
    {
        comboBox.Items.Add(item);
        items.Add(new SemiEditableComboBoxItem(initialText, fixedPrefix, editableSuffixChanged, enabled));
    }

    public int itemsCount
    {
        get
        {
            return comboBox.Items.Count;
        }
    }

    public void setItemEnabled(int index, bool enabledOrDisabled)
    {
        items[index].enabled = enabledOrDisabled;
    }

    public bool getItemEnabled(int index)
    {
        return items[index].enabled;
    }

    public void clearAllItems()
    {
        comboBox.Items.Clear();
        items.Clear();
    }

    public int selectedIndex
    {
        get
        {
            return currentlySelectedIndex;
        }
        set
        {
            this.comboBox.SelectedIndexChanged -= new EventHandler(comboBox_SelectedIndexChanged);
            comboBox.SelectedIndex = value;
            modifySelection = true;
            this.Invalidate();
            this.comboBox.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);
        }
    }

    public object selectedItem
    {
        get
        {
            return comboBox.Items[selectedIndex];
        }
    }

    public object getItem(int index)
    {
        return comboBox.Items[index];
    }

    public DrawMode drawMode
    {
        set
        {
            this.comboBox.DrawMode = value;
        }
    }
}

AnswerRe: Why isn't my semi-editable ComboBox drawing the text in gray when the dropdown list isn't showing? Pin
OriginalGriff10-Jan-23 3:46
mveOriginalGriff10-Jan-23 3:46 
GeneralRe: Why isn't my semi-editable ComboBox drawing the text in gray when the dropdown list isn't showing? Pin
arnold_w10-Jan-23 4:06
arnold_w10-Jan-23 4:06 
GeneralRe: Why isn't my semi-editable ComboBox drawing the text in gray when the dropdown list isn't showing? Pin
Ralf Meier10-Jan-23 4:55
professionalRalf Meier10-Jan-23 4:55 
GeneralRe: Why isn't my semi-editable ComboBox drawing the text in gray when the dropdown list isn't showing? Pin
arnold_w10-Jan-23 5:21
arnold_w10-Jan-23 5:21 
GeneralRe: Why isn't my semi-editable ComboBox drawing the text in gray when the dropdown list isn't showing? Pin
Ralf Meier10-Jan-23 6:14
professionalRalf Meier10-Jan-23 6:14 
AnswerRe: Why isn't my semi-editable ComboBox drawing the text in gray when the dropdown list isn't showing? Pin
Pete O'Hanlon12-Jan-23 0:03
subeditorPete O'Hanlon12-Jan-23 0:03 
GeneralRe: Why isn't my semi-editable ComboBox drawing the text in gray when the dropdown list isn't showing? Pin
arnold_w12-Jan-23 2:29
arnold_w12-Jan-23 2:29 
GeneralRe: Why isn't my semi-editable ComboBox drawing the text in gray when the dropdown list isn't showing? Pin
Pete O'Hanlon12-Jan-23 2:55
subeditorPete O'Hanlon12-Jan-23 2:55 
Questionproblem using ... "nested" DLL's ... a DLL referenced inside another DLL ? Pin
BillWoodruff8-Jan-23 21:30
professionalBillWoodruff8-Jan-23 21:30 
AnswerRe: problem using ... "nested" DLL's ... a DLL referenced inside another DLL ? Pin
Richard Deeming8-Jan-23 22:09
mveRichard Deeming8-Jan-23 22:09 
GeneralRe: problem using ... "nested" DLL's ... a DLL referenced inside another DLL ? Pin
BillWoodruff9-Jan-23 0:31
professionalBillWoodruff9-Jan-23 0:31 
GeneralRe: problem using ... "nested" DLL's ... a DLL referenced inside another DLL ? Pin
Richard Deeming9-Jan-23 0:45
mveRichard Deeming9-Jan-23 0:45 
GeneralRe: problem using ... "nested" DLL's ... a DLL referenced inside another DLL ? Pin
BillWoodruff9-Jan-23 2:10
professionalBillWoodruff9-Jan-23 2:10 
GeneralRe: problem using ... "nested" DLL's ... a DLL referenced inside another DLL ? Pin
Richard Deeming9-Jan-23 2:26
mveRichard Deeming9-Jan-23 2:26 
GeneralRe: problem using ... "nested" DLL's ... a DLL referenced inside another DLL ? Pin
BillWoodruff9-Jan-23 2:42
professionalBillWoodruff9-Jan-23 2:42 
AnswerRe: problem using ... "nested" DLL's ... a DLL referenced inside another DLL ? Pin
OriginalGriff8-Jan-23 22:19
mveOriginalGriff8-Jan-23 22:19 
GeneralRe: problem using ... "nested" DLL's ... a DLL referenced inside another DLL ? Pin
BillWoodruff9-Jan-23 0:38
professionalBillWoodruff9-Jan-23 0:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.