Entwickler-Ecke

WinForms - Zeichnen während listview column resize


Chiyoko - Sa 18.06.11 10:50
Titel: Zeichnen während listview column resize
Huhu,

Wie die Ueberschrift schon sagt, frag ich mich, wie über 2 Events(Changing/Changed) das zeichnen der Listview items unterbinden kann, sobald die Column width Eigenschaft geändert wird?

Bitte um Ratschläge,
Danke.


Chiyoko - Sa 18.06.11 22:49

Seit Wochen habe ich über gewisse Eventungewohnheiten gerätselt, aber ich habs endlich kapiert, ...wahrscheinlich falsch gelesen.So funktionierts:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
        private void listview_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e)
        {
            listview.BeginUpdate();
            listview.ColumnWidthChanged += new ColumnWidthChangedEventHandler(listview_ColumnWidthChanged);
        }
        private void listview_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs d)
        {
            listview.EndUpdate();
        }


Kha - Sa 18.06.11 23:39

Wozu den Eventhandler im Changing hinzufügen :gruebel: ? EndUpdate ist wohl idempotent, deswegen knallt es hier nicht, aber du häufst dadurch trotzdem einen Rattenschwanz an Delegates an.


Chiyoko - So 19.06.11 01:06

Weil ich das Event selbst nicht als Funktion in der Funktion aufrufen kann.

Oder hast du eine bessere Idee?
Ich will ja nicht, das es einfach nur funktioniert, es soll schon richtig sein.

Wenn s geht ohne:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
proteced override onResize(EventArgs e)
{
   base...
}

// Es geht auch ueber:
this.Redrawresize
// das zählt aber für alle Controls und ich möchte es spezifisch nur für das Event


Kha - So 19.06.11 09:36

user profile iconChiyoko hat folgendes geschrieben Zum zitierten Posting springen:
Weil ich das Event selbst nicht als Funktion in der Funktion aufrufen kann.
listview_ColumnWidthChanged rufst du doch jetzt auch nicht selbst auf? Wenn du die Zeile streichst und dafür das Event im Designer einhängst, wird dein Code genau das gleiche tun, nur etwas sinnvoller sein.


Chiyoko - So 19.06.11 10:50

Wenn dem so waere....wuerde ich nicht hier geschrieben haben:p...oder?

Wenn ich das Event nicht in dieser Methode aufrufe, sondern im Designer definiere, wird Endupdate nicht aufgerufen.


Chiyoko - Mo 20.06.11 18:33

Hast du denn eine bessere idee?

Ich hab den thread wieder aufgemacht, so kanns nicht bleiben.


Dr. Hallo - Mo 20.06.11 23:12

ich weiß nicht recht ob ich dein problem richtig verstehe, aber hier totzdem ein vorschlag:
benutze einen timer und stell das timer.interval = 10 (od. auch 5 oder gar 1).


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
        private void listview_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e)
        {
            listview.BeginUpdate();
            timer.Enabled = false;//timer aus und gleich wieder anstellen..
            timer.Enabled = true;//so verhinderst du den handleraufruf wärend der größenänderung..
        }
        private void timer_Tick(object sender, EventArgs e)
        {
            listview.EndUpdate();
            timer.Enabled = false;
        }


k.p. ob das aber hier funktioniert. glück auf!


Chiyoko - Di 21.06.11 08:05

Nein brachte leider nichts aber danke.

Nach wie vor gehts nur mit dem abonieren des Events in der Methode.


Chiyoko - Di 21.06.11 11:46

http://www.mycsharp.de/wbb2/thread.php?postid=3549074

In diesem Link wird auch ein Event in einer Methode abonniert, was ist denn nun korrekt?:D
Zumal das jetzt als einziges funktioniert.
Ich kann ja auch die Events wieder deligieren oder?


Kha - Di 21.06.11 12:28

Ich habe es mir mal angeschaut, da hast du wohl die Doku nicht genau genug gelesen:
Zitat:
If BeginUpdate is called more than once, EndUpdate must be called an equivalent number of times.



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
        bool columnWidthChanging = false;

        void listView1_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e)
        {
            if (!columnWidthChanging)
            {
                columnWidthChanging = true;
                listView1.BeginUpdate();
            }
        }

        void listView1_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
        {
            listView1.EndUpdate();
            columnWidthChanging = false;
        }


user profile iconChiyoko hat folgendes geschrieben Zum zitierten Posting springen:
In diesem Link wird auch ein Event in einer Methode abonniert
Aber einmalig. Das macht der Designer auch nicht anders, wenn du dir die .designer.cs einmal anschaust.


Chiyoko - Di 21.06.11 12:42

Was hat denn die Doku damit zu tun?
Danke, den Gedanken hatte ich schon seit anbeginn, wollte aber nix mit Variablen machen.

Dann verbleibe ich so..:=


Ralf Jansen - Di 21.06.11 13:38

Zitat:
Was hat denn die Doku damit zu tun?


Das sie eindeutig sagt das man BeginUpdate und EndUpdate gleich oft aufrufen muss. Du rufst aber EndUpdate n*mal und BeginUpdate nur 1 mal beim resizen auf. Wobei n für die Anzahl bisheriger resize Vorgänge steht.


Chiyoko - Di 21.06.11 14:30

Versteh ich nicht.
Ich hab doch genau einmal das Event waehrend des Resize und einmal für das Beenden des Resize.
Wenn ich die Maustaste loslasse, hat es genau einmal stattgefunden.

Das hat ehr was mit meiner Logik zu tun als mit der Doku.
Wenn es ein BeginUpdate gibt, muss es auch ein EndUpdate geben.
Aber in dem Fall wusste ich nicht, wie oft denn nun BeginnUpdate aufgerufen wird.

EDIT: bzw Endupdate.


Th69 - Di 21.06.11 17:31

Hallo Chiyoko,

bei jedem Aufruf von

C#-Quelltext
1:
listview.ColumnWidthChanged += ...                    

fügst du dem Event eine weitere Methode hinzu, d.h. beim ColumnWidthChanged-Ereignis wird dann auch mehrfach deine Methode aufgerufen (und damit auch mehrfach das EndUpdate).

Warum also registrierst du dieses Event dann nicht auch nur einmalig im Konstruktor (bzw. per Designer) - wie du es ja auch für das ColumnWidthChanging gemacht hast?


Chiyoko - Di 21.06.11 18:13

@Th69

Ja danke, ich infomier mich da nochmal im Netz.
Aber den Abschnitt hab ich nun verstanden^^
Der einfachste Weg ist doch manchmal der beste Weg;)


Kha - Di 21.06.11 21:14

Da ich aus deinen Beiträgen nicht herauslesen kann, ob du nun meine oder weiterhin deine Version benutzt: Der von mir erwähnte "Rattenschwanz" an Delegates, die am Changed-Event hängen, ist vor allem ein Memory Leak, benutz also bitte meinen Code ;) .


Chiyoko - Mi 22.06.11 07:17

Hab ich mich so missversändlich ausgedrückt?...ich finde eigendlich nicht.

Ich schrieb, dass mir deine Variante schon seit Anbeginn dieses Problems im Kopf bestand, ich es aber nicht nutzen wollte.
(Wusste aber auch nicht, ob es funktionieren würde hehe).

Auf jeden Fall nutze ich jetzt die boolische Variante, damit der Code sauber bleibt.
Das Problem mit den Delegates habe ich mir nochmal bestätigen lassen, als hier noch keine Antwort bestand.

Danke, ich weis fürs nächste mal bescheid^^