Combobox -FunktionalitätC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Combobox -Funktionalität

Post by Anonymous »

Ich möchte einen Combobox verwenden, um Elemente aus einer CSV -Datei auszuwählen. Wenn ich eine Zeichenfolge in den Combobox eingeben, sollte der Dropdown die Elemente angezeigt werden, die zu dem entsprechen, was ich eingeben. Wenn ein Teil einer Zeichenfolge aus der CSV -Datei mit meinem Text übereinstimmt, sollte sie in der Dropdown -Liste angezeigt werden. Ich muss in der Lage sein, mit Pfeil nach oben auszuwählen, und wenn ich die Eingabetaste drücke, sollte die Texteigenschaft des Comboboxs mit der ausgewählten Zeichenfolge aus der Dropdown -Seite gefüllt werden. Der Haken ist, dass, wenn ich eine Zeichenfolge einmachte, die keine Elemente aus der Dropdown -Down -Down -Sache übereinstimmt und dann die Eingabetaste drücke, das Programm mir darüber informieren sollte, dass keine Übereinstimmungen gefunden wurden. Im Moment erhöht der Code eine Ausnahme, die im Versuch begangen wurde ... Catch Loop. Unten ist der Code. Der CSV -Inhalt sind diese Begriffe, eine pro Zeile: cona, conb, conc, dab, dac < /p>

Code: Select all

using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace ComboBoxDB
{
public partial class Form1 : Form
{
// In-memory list to hold the CSV data.
private List items = new List();
// Path to your CSV file.
private string csvFilePath = "data.csv";

// Flags to track state
private bool _isUpdating = false;
private string _userTypedText = string.Empty;
private bool _isNavigating = false;
// Flag to suppress dropdown reopening after selection (via Enter)
private bool _suppressDropdownAfterSelection = false;

public Form1()
{
InitializeComponent();
LoadCSV();
SetupComboBox();
}

// Load the CSV file into the 'items' list.
private void LoadCSV()
{
if (File.Exists(csvFilePath))
{
items = File.ReadAllLines(csvFilePath).ToList();
}
else
{
items = new List { "CONA", "CONB", "CONC", "DAB", "DAC" };
File.WriteAllLines(csvFilePath, items);
}
}

// Set up the ComboBox with all needed event handlers.
private void SetupComboBox()
{
cbManPN.AutoCompleteMode = AutoCompleteMode.None;
cbManPN.AutoCompleteSource = AutoCompleteSource.None;
cbManPN.DropDownStyle = ComboBoxStyle.DropDown;

cbManPN.TextChanged += cbManPN_TextChanged;
cbManPN.KeyDown += cbManPN_KeyDown;
cbManPN.KeyUp += cbManPN_KeyUp;
cbManPN.SelectedIndexChanged += cbManPN_SelectedIndexChanged;
cbManPN.DropDownClosed += cbManPN_DropDownClosed;
cbManPN.SelectionChangeCommitted += cbManPN_SelectionChangeCommitted;
}

private void cbManPN_TextChanged(object sender, EventArgs e)
{
// Don't process if we're already updating or navigating.
if (_isUpdating || _isNavigating)
return;

_isUpdating = true;
_userTypedText = cbManPN.Text ?? string.Empty;

// We save these values in case we restore them below.
int selectionStart = cbManPN.SelectionStart;
if (selectionStart > _userTypedText.Length)
selectionStart = _userTypedText.Length;

this.BeginInvoke(new Action(() =>
{
try
{
var currentText = _userTypedText;
// Filter items (case-insensitive substring).
var filteredItems = items
.Where(i => i.IndexOf(currentText, StringComparison.OrdinalIgnoreCase) >= 0)
.OrderBy(i => i)
.ToArray();

cbManPN.BeginUpdate();
// Clear items and ensure no leftover selection.
cbManPN.Items.Clear();
cbManPN.SelectedIndex = -1;

if (filteredItems.Length > 0)
{
// Add new items and reset selected index.
cbManPN.Items.AddRange(filteredItems);
cbManPN.SelectedIndex = -1;

// Only open the dropdown if we have text and not suppressing.
cbManPN.DroppedDown = (currentText.Length > 0 &&  !_suppressDropdownAfterSelection);

// Update the ComboBox text and caret position to preserve user’s input.
cbManPN.Text = currentText;
if (cbManPN.Focused)
cbManPN.SelectionStart = selectionStart;
}
else
{
// If no matches, close the dropdown (but don't reset the text).
cbManPN.DroppedDown = false;
}

cbManPN.EndUpdate();
}
catch (Exception ex)
{
MessageBox.Show("Error in TextChanged update: " + ex.Message,
"TextChanged Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
_suppressDropdownAfterSelection = false;
_isUpdating = false;
}
}));
}

private void cbManPN_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
{
_isNavigating = true;
if (!cbManPN.DroppedDown && cbManPN.Items.Count > 0)
{
cbManPN.DroppedDown = true;
}

if (cbManPN.SelectedIndex == -1 && cbManPN.Items.Count > 0)
{
// If no item is selected, select first or last depending on arrow.
cbManPN.SelectedIndex = (e.KeyCode == Keys.Down) ? 0 : cbManPN.Items.Count - 1;
e.Handled = true;
}
}
else if (e.KeyCode == Keys.Enter)
{
// Prevent reopening the dropdown in TextChanged.
_suppressDropdownAfterSelection = true;
this.BeginInvoke(new Action(() => cbManPN.DroppedDown = false));

_isNavigating = false;
string finalText = cbManPN.Text;

if (!string.IsNullOrWhiteSpace(finalText))
{
// Check for partial matches with the same logic as TextChanged.
var filteredMatches = items
.Where(i => i.IndexOf(finalText, StringComparison.OrdinalIgnoreCase) >= 0)
.ToArray();

if (filteredMatches.Length == 0)
{
MessageBox.Show("No matching elements in the database.",
"No Match", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}

e.Handled = true;
e.SuppressKeyPress = true;
}
else if (e.KeyCode == Keys.Escape)
{
this.BeginInvoke(new Action(() => cbManPN.DroppedDown = false));
_isNavigating = false;

// Restore the original user-typed text.
_isUpdating = true;
cbManPN.Text = _userTypedText;
if (cbManPN.Focused)
cbManPN.SelectionStart = _userTypedText.Length;
_isUpdating = false;

e.Handled = true;
e.SuppressKeyPress = true;
}
else
{
_isNavigating = false;
}
}

private void cbManPN_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode != Keys.Down && e.KeyCode != Keys.Up)
_isNavigating = false;
}

private void cbManPN_SelectedIndexChanged(object sender, EventArgs e)
{
// Only update text if user is navigating with arrow keys.
if (_isNavigating &&  cbManPN.SelectedIndex != -1)
{
_isUpdating = true;
string selectedItem = cbManPN.SelectedItem.ToString();
cbManPN.Text = selectedItem;
if (cbManPN.Focused)
cbManPN.SelectionStart = selectedItem.Length;
_isUpdating = false;
}
}

private void cbManPN_SelectionChangeCommitted(object sender, EventArgs e)
{
// Handle mouse-based selection.
if (cbManPN.SelectedItem != null)
{
_isUpdating = true;
string selectedItem = cbManPN.SelectedItem.ToString();
cbManPN.Text = selectedItem;
if (cbManPN.Focused)
cbManPN.SelectionStart = selectedItem.Length;
_isUpdating = false;

this.BeginInvoke(new Action(() => cbManPN.DroppedDown = false));
_isNavigating = false;
}
}

private void cbManPN_DropDownClosed(object sender, EventArgs e)
{
// If the dropdown closed while navigating, decide what to do with the text.
if (_isNavigating)
{
_isNavigating = false;
if (cbManPN.SelectedIndex == -1 && !string.IsNullOrEmpty(_userTypedText))
{
_isUpdating = true;
cbManPN.Text = _userTypedText;
if (cbManPN.Focused)
cbManPN.SelectionStart = _userTypedText.Length;
_isUpdating = false;
}
}
}
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post