Verwendest du evtl. irgendwo in deinem Code listview.Clear()
anstatt listview.Items.Clear()
(denn ersteres löscht auch alle Spalten)?
Hallo und willkommen,
hast du dir schon das Beispiel unter ASP.NET Core Blazor QuickGrid-Komponente angeschaut?
Bei Items
muß man eine IQueryable<T>
angeben (und List<T>
ist keine).
Warum erzeugst du denn in dieser Methode jedesmal ein neues DataGridView
-Objekt?
Das Neuzeichnen mußt du selbst im Code anstoßen, d.h. mittels Invalidate()
, Refresh()
oder Update()
(lies dir die Unterschiede in der Doku dazu durch).
PS:
Statt direkt das DataGridView
auf einer Form
zu benutzen, solltest du bessere eine eigene Kalender-Komponente (als UserControl
oder von DataGridView
abgeleitetes Steuerelement) erzeugen.
Dein Code selbst ist auch noch verbesserungsfähig:
- Trennung von UI und Logik: benutze DataBinding mittels DataSource
- dementsprechend Auslagerung von Code in eigene Klassen/Methoden
- inkonsistente Datumsbehandlung (Split
vs. Parse(Exact)
): bei Verwendung von direkt DateTime(Offset)
als Datenwert aber eh unnötig
- Performanceoptimierung im CellFormatting
-Ereignis (unnötige mehrfache Farbzuweisung je Zeile)
Und welche Fehlermeldung erscheint?
Die Methode gibt es auch in .NET 8: Type.GetTypeFromProgID
Der Rückgabetyp ist aber Type?
, d.h. je nach Einstellung der Projektoption Nullable (Standard: enabled
) gibt es dann einen entsprechenden Fehler, wenn die Variable nicht auch als Type?
deklariert ist (s.a. Kreuzzug gegen Null-Referenz-Exception in C# 8.0).
Es ist aber eigenartig, daß vom Explorer aus immer alle Bilder des Ordners in der Windows-Fotoanzeige durch Navigation angeschaut werden können. Vllt. gibt es eine interne Kopplung zwischen beiden Programmen?
Ich habe selber nun mal versucht eine Bilddatei bei mir genauso zu öffnen - aus der Konsole heraus.
Aber weder ein "cd /D <path>" noch die Angabe des Pfads zeigt (wie bei dir) die anderen Bilder in der Windows-Fotoanzeige an. Ich habe sogar noch eine Batch-Datei erstellt, aber auch dies funktioniert nicht wie gewünscht.
Intern benutzt der Windows-Explorer die Funktion ShellExecute zum Öffnen von Dateien und eigentlich sollte UseShellExecute = true
diese Funktion intern dann ebenso verwenden, aber anscheinend ist doch noch etwas anders.
Evtl. benutzt der Explorer auch die erweiterte Funktion ShellExecuteEx (mit einer eigenen Struktur als Parameter), die sich dann anders verhält?
Du könntest diese Funktion auch selber mit C# verwenden, s. PInvoke.net/ShellExecuteEx (Shell32)., müßtest aber selber die passenden Werte für die ShellExecuteInfo-Struktur durch Doku-Lesen und Ausprobieren herausfinden.
Du solltest aber generell dann schon mal mit PInvoke/Interop gearbeitet haben.
PS:
Du hast Recht mit dem Explorer (evtl. hat sich das seit einigen Windows-Versionen geändert?). Ich habe sonst immer das Konsolenkommando "start" (bzw. nur den Dateipfad+Name) dafür benutzt.
Hast du denn in _file
weiterhin auch den kompletten Pfad drin stehen?
Und was passiert, wenn du bei dem Bild in der Windows-Fotoanzeige die Taste F
(Filmstreifen) drückst? Siehst du dann die anderen Bilder des Ordners?
PS: Dein 2. Code ist logisch falsch, da der Windows-Explorer nicht (direkt) eine einzelne Datei als Parameter entgegennimmt, sondern man bestimmte Optionen angeben muß, s. z.B. File Explorer command line arguments in Windows 10.
Und außerdem würdest du damit nur die Datei (bzw. den Ordner) im Explorer anzeigen, nicht das zugehörige Programm öffnen.
Ich hatte oben noch mal ein "Edit" hinzugefügt.
In diesem Code tauchen auch die Werte 44
sowie 52
auf. Nach kurzer Internetsuche habe ich dazu Finding the aspect ratio gefunden (dieses scheinen also festdefinierte Werte zu sein für die auf dem Amiga gebräuchlichen Auflösungen bzw. Darstellungen am Monitor).
Bei den beiden Werten geht es ja um die Skalierung, d.h. sie geben das Verhältnis von X zu Y (d.h. Breite zu Höhe) an. Da hierfür nur ein Byte im BMHD
-Header zur Verfügung steht, können hier auch kleinere Zahlen drin stehen (z.B. 4 : 3, 16: 10, etc.), es geht ja nur um das Verhältnis X/Y.
Und in PageWidth
und PageHeight
sollte die ursprüngliche Screen-Auflösung drinstehen, mit der des Bild dargestellt wurde (vor dem Abspeichern).
Wenn jetzt das IFF-Bild geladen wird, kann dann auf dem System entweder die Auflösung anhand der PageWidth
und PageHeigth
angepaßt werden (beim Amiga z.B. einen neuen Screen in dieser Größe erzeugen) oder alternativ anhand des Aspekt-Ratio berechnet werden (damit die Anzeige nicht verzerrt aussieht).
Was für Werte hast du denn bei deinen Bildern drin stehen (und welche Originalauflösung hast du beim Abspeichern der Bilder auf dem Amiga verwendet)?
Edit:
Diesbzgl. ist sogar ein Fehler im Amiga-Code von modules/2Filbmw.c , da dort direkt die Werte von DI.Resolution.x
und DI.Resolution.y
zugewiesen werden. Da diese jedoch als WORD
, d.h. ushort
, gespeichert sind, wird nur das Low-Byte übernommen...
Wenn du das Projekt weiterführen möchtest, dann wäre jetzt der richtige Zeitpunkt, so wie ich schon im ersten Beitrag geschrieben habe, die Funktionalität in eine eigene Klasse (und einer eigenen Datei) - anstatt in der Forms-Klasse - auszulagern. Dazu am besten sogar ein eigenes Bibliotheks/Library-Projekt erzeugen und als Referenz in dem WinForms-Projekt hinzufügen.
Wenn du deinen Code mit dem aus dem IFF-ILBM-Parser vergleichst, dann siehst du, daß dein Code um einiges komplizierter (und inperformanter) ist - gerade was auch die Bitoperationen betrifft. Auch die von mir erwähnte Schleifenverschachtelung (Height / Depth / Width) wird ja von diesem Projekt verwendet.
Aber es ist ja gut, wenn du dich selber intensiv mit dieser Thematik beschäftigst und dann selbst auf Lösungen kommst.
Kannst ja erstmal deinen Code ein bißchen aufräumen und dokumentieren.
Wenn du weitere Tipps benötigst, so kannst du dich ja jederzeit melden.
Gratulation!
Was war denn noch der Fehler? Und kannst du den Code hier als Anhang hinzufügen?
So ganz verstehe ich aber nicht, was Chrome oder Edge mit Outlook zu tun hat?
Und wenn nur die Dateinamen geliefert werden, dann ist das ein Fehler von diesen Programmen. Außer es gibt evtl. ein Standardverzeichnis dafür?
Hast du denn jetzt auch mal meine geposteten Methoden benutzt?
Aber wenn du die Dateinamen hast, dann kannst du damit doch die Bilder per new Bitmap(filename)
laden (oder sind dort keine Pfade hinterlegt, sondern nur die reinen Dateinamen?).
Außerdem gibt es auch noch "FileGroupDescriptor"
(für die ANSI-Texte). Dazu gefunden habe ich Outlook Drag and Drop in C# (weiß aber nicht, ob dir das weiterhilft oder noch mehr verwirrt).
Zitat von schorge
bei z.B. Bilder aus Chrome oder Edge bekomme ich nur FileNames und MemoryStream gibt null aus.
Hast du schon einfach versucht mittels ContainsFileDropList und GetFileDropList an diese Dateinamenliste zu gelangen?
Ansonsten kannst du auch mittels GetFormats zuerst schauen, in welchen Formaten das Drag&Drop-Objekt vorliegt.
Nein, darum geht es nicht, und zwei gleiche Methoden mit unterschiedlichen Rückgabetypen sind auch gar nicht möglich.
IEnumerator IEnumerable.GetEnumerator()
ist eine Explicit Interface Implementation und diese wird aufgerufen, sobald man über das Interface die GetEnumerator
-Methode benutzt, z.B.
IEnumerable list = ...;
foreach (object x in list)
{
}
(bzw. bei dir über das davon abgeleitete Interface ISubClass
)
Man kann zwar mehrere explizite Interface-Implementierungen angeben, aber diese müssen dann auch explizit (daher der Name) über das zugehörige Interface aufgerufen werden.
Und bei der generischen Methode IEnumerator<IClass> GetEnumerator()
ist eben vom Compiler sichergestellt, daß auch nur IClass
(bzw. deren Basisklassen)-Objekte bei der Zuweisung akzeptiert werden.
Die Abfrage
if (position >= items.Count) return false;
wird bei einer leeren Liste nicht erfüllt (und daher der weitere Code ausgeführt, welcher dann true
zurückgibt und somit dann auf Current
zugegriffen wird → IndexOutOfRangeException
).
Und auch beim letzten Element-Index items.Count - 1
nicht.
Also muß es so aussehen:
if (position >= items.Count - 1) return false;
Du solltest mal die Warnungen überprüfen.
Auch der aufrufende Code muß await
benutzen - ansonsten wird der ganze Code synchron ausgewertet.
Außerdem erscheint mir NavigateToString die falsche Methode (diese erwartet einen HTML-String, keine URL), sondern entweder die Eigenschaft Source oder CoreWebView2.Navigate.
Hallo Mezzo,
hast du schon mal nach dem englischen Wort "swipe" gesucht?
Gefunden habe ich bei "WPF swipe control" u.a. WPF-FlipView.
PS: Bei MAUI gibt es ein ähnliches Control namens "CarouselView".
Ich hatte dir doch auch den Link zu dem IFF-Parser gegeben. Schau dir einfach die Methode IFF.cs: ReadBody an. Bei 24 Bit Bildern ist dann BMHD.NPlanes
dann eben 24 - und nur die Methode ColorIndexToColor
ist dabei dann zu viel, da iColor
schon den Farbwert (als uint
) angibt.
PS:
Du hast Recht, bei einem Masking
-Wert von 1
sollte es jeweils eine Ebene (Bitplane) mehr pro Zeile geben (da hat dann wohl XnView einen Fehler).
Und wegen den zwei Nullen nach dem Chunk-Namen: nach jedem Chunk-Namen (z.B. BMHD
) kommen noch mal 4 Bytes als Chunk-Länge (in Big Endian Format), so daß bei Daten kleiner gleich 0xFFFF
eben zwei Nullen am Anfang sind (so daß dann z.B. dort für die fixe BMHD-Größe von 20 (= 0x14
)00 00 00 14
steht).
Daß du bei keinem deiner Versuche grau für die ersten Zeilen herausbekommst, ist schon eigenartig, denn das bedeutet, daß die Daten irgendwie anders codiert sind.
Trotzdem scheint ja die vorherige Version (das Bild mit den Streifen) schon in die richtige Richtung zu gehen. Eigenartig ist jedoch, daß dort rechts im Bild plötzlich der Hintergrund von weiß auf schwarz wechselt.
Du hast ja etwas von 90° gedreht geschrieben - versuche doch mal die Breite und Höhe zu tauschen (also nur 600 pro Zeile zu lesen).
Edit:
Ich habe unter IFFshow/iff24.py ein Python-Script zum Erzeugen von 24bit IFF-Bildern gefunden.
Anscheinend ist es wirklich so, daß die Farbbits je Ebene (plane) aufgeteilt sind, d.h. es gibt insg. 24 (3 * 8) Ebenen je Zeile (und jede Zeile besteht dann aus Width / 8
Bytes).
Sorry für das Mißverständnis: ich hatte immer gedacht die z.B. R0 - R7 beziehen sich auf die Bits eines gelesenen Bytes, aber sie sind verteilt auf die verschiedenen Ebenen. Mein Eingangsbeitrag stimmte also (fast), nur daß die Bildtiefe dann 24 (und nicht nur 3) ist.
Also unterscheidet sich 24 Bit von x-Bit Paletten-Bildern nur dadrin, daß einfach mehr Ebenen (planes) abgespeichert sind (und anstatt eines Index in die Farbpalette direkt der 24 Bit Wert die RGB Farbe ergibt).
Edit2:
Die Original IFF-Formatbeschreibung habe ich nun auch unter ILBM IFF Interleaved Bitmap gefunden (dort sieht man auch die richtige Formatierung unter "24-bit ILBMs" - fast ganz unten).
Eine weitere gute Beschreibung habe ich unter IFF gefunden (auch dort sind 24 Bit IFF-Bilder genauer erklärt).
Und ich habe sogar jetzt Original Amiga C-Code online gefunden: IFFSource Code: apps/24bitDemo/24bitDemo.c
Hast du dafür den zuletzt geposteten Code verwendet? Was kommt denn raus, wenn du deinen Originalcode darauf anwendest?
Und kannst du mal das IFF Bild hier anhängen (als ZIP)?
PS: In der GUI und im Code ist "Kompression" falsch geschrieben.
N'Abend,
wird denn AddBuildVersion
auch vor dem Serialisieren aufgerufen? Ansonsten kannst du mal mit dem Debugger überprüfen, was in DataSource.BuildVersion
drin steht, s. [Artikel] Debugger: Wie verwende ich den von Visual Studio?
PS:
C# 4 ist aber schon ziemlich alt (von 2010 für .NET Framework 4.0), s.a. C#: Versionen.
Kannst du nicht auf ein neueres Framework (+ C#-Version) wechseln? Oder benutzt du noch VS 2010?
Evtl. hattest du doch recht mit deinem vorherigen Code, denn laut ILBM IFF Interleaved Bitmap: 24-bit ILBMs liegen R, G, B direkt hintereinander im Speicher (und die Bitreihenfolge ist vertauscht?).
Es wäre schön, wenn du den Code in C#-Code Tags packen würdest.
Auf die Schnelle sehe ich bei dir keinen inhaltlichen Fehler.
Hast du überprüft, ob rotByteIndex
bzw. rotByteArray
(btw.: Warum hast du zwei verschiedene Variablen hierfür?) nach der Schleife auch den Wert von byteBody
hat?
Kannst du nicht mal mit einem kleineren Bild (z.B. 16x16) testen? Ich selber habe dafür IrfanView (mit installiertem IFF Plugin) benutzt. Ich habe es aber nicht mehr hier installiert - weiß also nicht, ob es auch 24 Bit unterstützt oder nur Bilder mit einer Farbpalette.
PS: Mir hättest du nicht im Detail erklären müssen, wie das IFF/ILBM-Format aufgebaut ist.
Du brauchst ja dann auch nicht mehr von dort aus darauf zugreifen, da du den gesamten Code aus btnOk_Click
(bis auf Close()
) in die andere Form-Klasse verschiebst:
private void btnAdd_Click(object sender, EventArgs e)
{
AddForm addForm = new AddForm(this);
if (addForm.ShowDialog() == DialogResult.OK)
{
DataItem dataItem = new()
{
Name = addForm.ItemName,
Description = addForm.Description,
Status = addForm.Status
};
AddDataItem(dataItem);
}
}
private void AddDataItem(DataItem dataItem)
{
string[] subItems = { dataItem.Description, dataItem.Status };
listView1.Items.Add(dataItem.ItemName).SubItems.AddRange(subItems);
DataSource.DataList.Add(dataItem);
}
private DataSource DataSource { get; private set; } = new();
Und dann nur noch die passenden Eigenschaften ItemName
,Description
und Status
in der AddForm
-Klasse (wie in meinem letzten Beitrag gezeigt) anlegen (Name
habe ich in ItemName
umbenannt, da es diese Eigenschaft ja schon bei Form
/ Control
gibt).
OK, mit einer externen Grafikkarte geht das sicherlich, aber ich meinte einen Original Amiga 500 (bzw. bis 4000). Mit dem Hold-And-Modify-Modus (HAM) kann man zwar mehr Farben gleichzeitig anzeigen, jedoch ist das Format dafür auch um einiges komplexer (gibt dafür auch extra bei IFF-Bildern einen eigenen Typ), so daß dieses nicht so einfach konvertiert werden kann.
Also da heißt bei einer Grafik von 800 x 600 würden zuerst 800 Byte für Rot kommen, dann 800 Byte für Grün und dann 800 für Blau.
Genau!
Hallo, dachte schon, du würdest dich nicht mehr melden.
Dein Gedankengang ist aber teilweise falsch - hast du dir nicht den Wikipedia-Artikel angeschaut?
Der BODY-Block ist, wie ich schon geschrieben habe sowie es im Wiki-Artikel steht, zeilenweise aufgebaut, d.h. erst kommt die erste Zeile für R(ot), dann die erste Zeile für G(rün), dann die erste Zeile für B(lau) und erst danach dann die zweite Zeile R(ot), zweite Zeile G(rün), zweite Zeile B(lau), ...
Und bei einer 24-Bit Grafik besteht jeder Pixel aus genau 3 Bytes, d.h. du benötigst keine Bitoperationen (diese werden nur für die Palettenindizes beim CMAP-Block benötigt). Ein Byte aus dem BODY-Block entspricht also jeweils dem R, G oder B-Wert eines Pixels. Du mußt diese dann nur nach jeder Zeile pixelweise jeweils zu einem Color
- Wert zusammensetzen.
Sorry, ich hatte bei deinem Eingangsbeitrag überlesen, daß du eine 24Bit IFF-Grafik einlesen willst. Aber wie kann der Amiga diese denn darstellen, denn er kann doch nur max 32 (bzw. 64 im Extra-Halfbrite-Modus) gleichzeitig anzeigen?
Kannst du nicht einfach ein NumberFormatInfo
dafür erstellen (und dies dann einer CultureInfo
zuweisen), s.a. Standardmäßige Zahlenformatzeichenfolgen: Spezifizierer für Währungsformat (C) ?
Ansonsten schau auch mal in WpfCurrencyTextbox rein.
Hallo ThaKilla,
mit dem Code aus deinem Eingangsbeitrag bist du schon auf dem richtigen Weg (besser als die DataSet
/ DataTable
-Serialisierung), nur daß du eben dein Datenmodell (so wie Abt schon geschrieben hat) anpassen mußt:
[XmlType("Data-Source")]
public class DataSource
{
public BuildVersion BuildVersion { get; set; } = new();
public List<DataItem> DataList { get; set; } = new();
}
public class BuildVersion
{
public string Version { get; set; }
}
public class DataItem
{
public string Name { get; set; }
public string Description { get; set; }
public string Status { get; set; }
}
Anstatt einer List<...>
erzeugst du dann ein einzelnes DataSource
-Objekt (welches ein BuildVersion
-Objekt und eine Liste der Daten enthält) und serialisierst dieses dann.
Außerdem solltest du das Erzeugen des DataItem
-Objekts (welches bei dir noch myObject
heißt) nicht in dem Code des AddForm
-Dialogs durchführen, sondern nach dem Aufruf in der Hauptform, s. mein Artikel Kommunikation von 2 Forms unter "1. Hauptform ruft Unterform mittels ShowDialog() auf".
Dazu dann einfach (nur lesende) Eigenschaften in AddForm
hinzufügen, z.B.
public string ItemName => txtName.Text;
Dann benötigst du auch keine Referenz mehr auf die Hauptform UpdateMaker
.
Auf dem Projekt aufbauend gibt es noch BlazorCanvas (welches erst vor ein paar Monaten auf .NET 8 aktualisiert wurde).
Hallo und willkommen,
für einen Programmieranfänger ist das aber schon eine herausfordernde Aufgabe!
Woher kommen denn bildBreite
und bildHoehe
- und welche Werte haben diese? Solltest du diese nicht auch aus der IFF-Datei lesen (s.a. Interchange File Format)? Und selbstverständlich solltest du die Chunks lesen (und nicht mit festen Offsets arbeiten).
Edit:
Ich habe gerade noch mal bei meinem eigenen C-Code für die alten Amiga-Programme nachgeschaut. Das ILBM-Format funktioniert anders als dein bisheriger Schleifencode - die Schleifen sollten so aufgebaut sein:
Height
Depth
Width
Es gibt also je Farbkanal (Depth
= 3 für RGB) jeweils eigene Bildzeilen (und nicht pro Pixel die 3 RGB-Werte hintereinander), s.a. Interchange File Format: BODY-Chunk!
Bedenke auch, daß du die Width
(bzw. bei dir bildBreite
) durch 8
teilen mußt, um die Anzahl der zu lesenden Bytes zu bestimmen - und dann Bitoperationen benötigst um den Farbkanal-Pixelwert für die einzelnen 8 Pixel je Byte auszulesen → ist also nicht so direkt on-the-fly umwandelbar: erzeuge am besten eine eigene Klasse mit entsprechenden Datentypen und Methoden dafür.
Deinen Schleifencode könnte man außerdem noch aus Performancegründen verbessern, indem man LockBits
und Scan0
verwendet, anstatt SetPixel
.
Edit2: Vllt. verwendest du (gerade als Programmieranfänger) doch besser eine Library, z.B. IFF-ILBM-Parser.
PS: Und verwende Code-Tags bei deinem Beitrag (solltest du auch noch nachträglich editieren können).
Hallo,
das hast du richtig erkannt, die for
-Schleife ist dort falsch (und auch überflüssig).
Du benötigst anstatt der Schleifenvariablen eine lokale Variable (wie lagerraum
), welche die Anzahl der bisher eingelesenen Kisten speichert (und diese mußt du nach dem erfolgreichen Einlesen um 1 erhöhen).
Ich nehme mal an, du hast bisher noch nichts von List<T> gelesen? Dies ist ein dynamisches Array und du bräuchtest nicht das Array mit einem festen Wert vorzuinitialisieren und die Länge speichert es auch automatisch.
Für die Fehlerbehandlung kannst du noch den Fall case default:
hinzufügen, s.a. Die Anweisung switch.
Anstatt Ausnahmen (Exception
) abzufangen (z.B. für Convert.ToInt32(...)
), würde man hier besser die TryParse
-Methoden benutzen, z.B. für int
: Int32.TryParse.
Zitat von bigeddie
Habe ein ABO für microsoft365.
Wenn du nur den Online-Zugriff mittels Microsoft 365 Online hast, dann funktioniert damit kein Office Interop. Du benötigst schon die lokale Office Installation.
Wie die anderen aber schon geschrieben haben, ist die Frage, ob du wirklich Office Interop benötigst oder doch nur reine Dokumentenbearbeitung durchführen möchtest?
Hast du denn ein bestehendes, altes Projekt, das du aktualisieren möchtest oder geht es um ein neues?
Hast du denn auch die passende Office-Version 15 (Office 2013) bei dir lokal installiert?
Bei neueren Versionen benötigst du auch geänderte referenzierte Assemblies. Evtl. hilft dir dabei NetOffice (ich weiß aber nicht, ob das noch aktuell ist?).
Mit welchen Werten von e.RowIndex
und e.RowCount
wird denn die RowsAdded
-Eventmethode aufgerufen?
Dein Code ist aber noch verbesserungsfähig:
CellClick
auf +
ein neues DataGridView
-Objekt (CreateDataGridViewContacts()
)?ContactDao
-Objekt?dataGridViewC.Rows[i]
solltest du eine lokale Variable (Referenz) dafür erstellen.PS: Was macht contactDao.ToggleCouple(...)
, da du weder den Rückgabewert auswertest noch anderweitig danach Code diesbzgl. ausführst?
Und mir ist noch aufgefallen, daß du in der RowsAdded
-Eventmethode zuerst auf Cells["id"].Value.ToString()
zugreifst bevor auf null
getestet wird...
Bei einer select
-Abfrage kann es auch sein, daß der SQL Server einen "full table scan" durchführt (und dies kann bei großen Datenmengen entsprechend lange dauern), daher solltest du dann passende Indizes für die Tabelle(n) setzen.
Auch hier dazu, wie in deinem anderen Beitrag, die Empfehlung im SQL Management Studio den Ausführungsplan anzuschauen.
Und kommt der Timeout denn bei der von dir angegeben Zeit (Connection Timeout=50
) oder aber schon früher?
Edit: Laut How to increase the sqlconnection timeout using program file in .net core 7 heißt es aber Connect Timeout
!
Abt hat dir doch, wenn auch auf den englischen Artikel, den Link dazu gegeben.
Hier noch mal der deutsche: Übersicht über den Ausführungsplan
Und in dem dort verlinkten Anzeigen eines tatsächlichen Ausführungsplans findest du das genaue Vorgehen dazu.
Und eine genauere Erklärung dazu für ein Insert
-Kommando gibt es in dem (englischen) Artikel Understanding Execution Plans of the SQL Server Insert statement.
PS: Hast du auch mein "PS" im letzten Beitrag gelesen (den ich noch nach-editiert hatte)?
PPS: Bin mit deinen 2 Beiträgen durcheinander gekommen, da ich beide bei mir als Tabs geöffnet hatte und dann in diesem statt in dem anderen gepostet habe.
Kommt der Timeout immer bei einer bestimmten Abfrage oder bei verschiedenen?
Und hast du dir schon im SQL Management Studio den Ausführungsplan dazu, wie von Abt schon vorgeschlagen, angeschaut?
PS: Habe mir gerade deinen Sourcecode angeschaut - du solltest dringend [Artikelserie] SQL: Parameter von Befehlen verwenden.
Außerdem führst du auch bei jeder Zeile mittels UpdateProgressBar
ein UI-Update durch - das auch Zeit kostet.
Wenn du dies außerdem auch noch im Main-/UI-Thread durchführst, blockierst du bei großen Datenmengen die UI: [FAQ] Warum blockiert mein GUI?
Desweiteren solltest du DataBinding benutzen, d.h. DataGridView.DataSource, und nicht einzeln die Zeilen per Rows.Add
hinzufügen.
Du übergibst dort doch mit e.Item
ein TreeNode
(und kein TreeView
-Objekt), d.h. du mußt dann auch
TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
verwenden (s.a. Beispiel von TreeView.ItemDrag). Und mit dessen TreeView -Eigenschaft kannst du dann auf dessen Eigenschaften zugreifen.
Edit:
Oder aber du übergibst direkt sender
, wenn du nur an dem TreeView
-Objekt interessiert bist.
PS: Das enthaltene Objekt kannst du auch direkt im Debugger anschauen: [Artikel] Debugger: Wie verwende ich den von Visual Studio?
Was übergibst du denn bei DoDragDrop
als ersten Parameter?
PS: Du hast im falschen Subforum gepostet - evtl. verschiebt es aber ein Moderator nach "Windows Forms".
Edit: Danke.
Zitat von fiedelbambu
... bei der Thailändischen sprache habe ich noch Probleme. Das wird sich bestimmt auch noch lösen lassen
Siehst du bei der Ausgabe nur Fragezeichen oder andere Symbole? Das liegt an der Codepage der Windows Konsole (diese steht standardmäßig nicht auf UTF-8).
Ab .NET 8 sollte dies aber geändert worden sein: .NET 8 Breaking Changes: CLI-Konsolenausgabe verwendet UTF-8
Oder du stellst es im Programm mittels Console.OutputEncoding um:
Console.OutputEncoding = Encoding.UTF8;
In Localization in DotNet via a simple example wird dies auch noch mal genauer (mit Bildern) erklärt.
Dies sollte mit einem Post-Build gelingen:
if "$(Configuration)" == "Intern" rename "$(TargetPath)" "appIntern.exe"
Ansonsten schau mal bzgl. "Publish" in die Antworten von How to change the output name of an executable built by Visual Studio (Stichwort: "<Target ... />").
Das ist ja schon mal gut, daß du die Ursache finden konntest.
Ich habe Maui.VirtualListView gefunden (weiß aber nicht, ob das auch mit Bildern so gut funktioniert).
Kannst du mal ausprobieren, wie die Performance bei weniger Bildern ist (z.B. 50, 100, 200), also ob es generell auftritt oder ob es kontinuierlich schlechter wird, je mehr Bilder angezeigt werden?
Meine Erfahrung ist auch, daß Android bei vielen Daten deutlich langsamer ist als Windows.
Und sind die Bilder denn im Original viel größer als 150x150, d.h. werden diese zur Anzeige stark skaliert?
Edit:
In [.NET 8 & .NET 7] Poor performance in scrolling in the image list. werden ähnliche Performance-Probleme beschrieben (ich habe aber nicht alle Beiträge gelesen).
Ich meine nur den Text-Hintergrund, nicht die obere Button-Leiste (das wäre wohl wirklich zuviel Aufwand, wenn es der CKEditor nicht selber unterstützt).
Kann man nicht auch den Texthintergrund dann auf "dunkel" setzen: Change the background color of the CKEditor text area?
Gefunden habe ich auch noch Dynamic Body Color using CKEditor (ich weiß aber nicht, ob das weiterhilft?).
Ja, sehe ich auch genau so.
Außerdem ist der Code bzgl. des Cachen der Icons anhand des MainWindowHandle
nicht durchdacht, denn z.B. nach einem Neustart ändern sich diese ja und es würden die falschen Icons angezeigt.
Und noch ein Tip:
Directory.CreateDirectory
testet intern schon, ob das Verzeichnis existiert (und macht dann nichts), daher braucht man nicht vorher noch auf Directory.Exists
abfragen (außer man möchte noch anderen Code zusätzlich aufrufen). Und mehrfach GetDirectoryName
aufzurufen verbraucht auch unnötigen Speicher und Performance.