Autor Beitrag
Talemantros
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Fr 22.05.15 09:45 
Hallo,
ich habe eine Form, wo der Benutzer über mehrere Comboboxen Filtern können soll und diese Ergebnisse in einem DataGridview angezeigt bekommt.
Dies funktioniert auch.
Da er aber nur immer eine Combobox nutzen soll und nicht in einer Kreuzabfrage wollte ich beim Klick auf eine Combobox alle anderen "zurücksetzen"

Dazu habe ich

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
        private void ResetFilter(Control form)
        {
            {
                foreach (Control control in form.Controls)
                {
                    if ((control is KryptonComboBox) && (control.Text != string.Empty))
                        ((KryptonComboBox)control).SelectedIndex = -1;
                    else
                        ResetFilter(control);
                }
        }


Auch dieser Teil funktioniert mit ResetFilter(this)
Leider setzt er aber auch die Combobox zurück, die das ganze ausgelöst hat.
Jetzt dachte ich könnte den Sender, der das ausgelöst hat abfragen und irgendwie die Eigenschaft .Name dann in der if Abfragen.

Da komme ich aber nicht so richtig weiter.

Danke

Gruß
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 22.05.15 10:07 
Zitat:
Jetzt dachte ich könnte den Sender, der das ausgelöst hat abfragen und irgendwie die Eigenschaft .Name dann in der if Abfragen.


Name ist nicht hilfreich. Da kann irgendwas drinstehen, nix drinstehen, oder in allen Controls kann überall der gleiche Name drinstehen. Name hat keine logische Bedeutung und man sollte sich davor hüten dem eine Bedeutung zu geben. Macht nur ärger.

Du kannst einfach die Controls vergleichen. Du rufst das ja vermutlich aus irgendeinem Event auf, wenn du die Schleife dort hättest könntest du einfach control != sender checken. Du kannst aber genauso den sender in deine Methode mit transportieren um da zu vergleichen.

Den Parameter form zu nennen finde ich unglücklich. Da du das rekrusiv aufrufst ist das maximal beim ersten mal eine form.

Je nach Event von wo du denn Code aufrufst solltest du aufpassen. Eventuell feuert das setzen von SelectedIndex auch diesen Event. Dann hast du dir eine schöne Kaskade gebaut die immer alles resetet da durchs reseten alle anderen Control sich gegenseitig reseten.
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Fr 22.05.15 14:24 
Hallo Ralf,
habe es jetzt so probiert

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
        private void ResetFilter(Control control, object sender)
        {
            try
            {
                foreach (Control ctrl in control.Controls)
                {
                    if ((ctrl is KryptonComboBox) && (ctrl.Text != string.Empty) && (ctrl != sender))
                        ((KryptonComboBox)ctrl).SelectedIndex = -1;
                    else
                        ResetFilter(ctrl, sender);
                }
            }
            catch (Exception ex)
            {
                MySqlError.SetError(ex.Message, this.ToString(), Global.GetCurrentFunctionName());
                MsgAusgabe.ShowError(ex.Message);
            }
        }


Aufruf durch

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
        private void cmbReNr_SelectionChangeCommitted(object sender, EventArgs e)
        {
            ResetFilter(this, sender);
            switch (showModul)
            {
                case 52:
                    ShowData(ScheineListenMethods.GetDataTableRechnungByID(Convert.ToInt64(cmbReNr.SelectedValue)));
                    break;
                case 53:
                    break;
                case 54:
                    break;
            }
        }


Jetzt setzt er aber trotzdem noch die aufrufende Combobox mit zurück.
Weiterhin ist mir aufgefallen, dass er den Index der Combobox nicht auf -1 setzt, sondern den Index um 1 reduziert.
Heißt so viel, dass wenn der Benutzer vorher den 5ten Eindruck also Index genommen hatte, dass er dann auf INdex 3 geht statt die Box zu leeren.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 22.05.15 15:02 
Zitat:
Weiterhin ist mir aufgefallen, dass er den Index der Combobox nicht auf -1 setzt, sondern den Index um 1 reduziert.


Verhält sich eine normale ComboBox auch so?
Habe das gerade versucht nachzustellen und mit einer Standard ComboBox verhält sich das richtig.


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
private void ResetFilter(Control form, Control ignoreCtrl)
{
    foreach (ComboBox cb in form.GetChildControls<ComboBox>())
        if (cb != ignoreCtrl && cb.SelectedIndex != -1)
            cb.SelectedIndex = -1;
}

private void cb_SelectionChangeCommitted(object sender, EventArgs e)
{
    ResetFilter(this, sender as Control);


public static class ExtensionMethods
{
    /// <summary>Gets all child controls, including indirect childs, of type T</summary>
    /// <typeparam name="T">The type of controls that should be found. Includes derived types of T</typeparam>
    public static IEnumerable<T> GetChildControls<T>(this Control root) where T : Control
    {
        var controls = root.Controls.Cast<Control>();
        return controls.SelectMany(c1 => GetChildControls<T>(c1)).Concat(controls).Where(c2 => typeof(T).IsAssignableFrom(c2.GetType())).Cast<T>();
    }
}


Edit : Du solltest mal über dein Exception Handling nachdenken ;) Eine Exception in einer rekursiven Funktion zu fangen, diese zu schlucken und stattdessen eine MessageBox anzuzeigen klingt nach Userfolter. Ein Fehler in dem Code wird vermutlich wiederholt auftreten. Da du einfach fortsetzt stellt sich die Frage wie oft der User die MessageBox wegklicken soll bevor er Aggressionen entwickelt ;)
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Di 26.05.15 13:48 
Vielen Dank für den Quellcode.
Habe es getestet und mit der KryptonCombobox funktioniert es einfach nicht.
Mit "normalen" schon.

Schade :-(

Das macht es komplizierter, nur weil ich wollte dass es etwas hübscher ist.


Gruß