Es funktioniert!
Ich hatte einen saublöden Fehler gemacht: ich hatte die RichTextBox auf Readonly gesetzt, damit kein User da was ändern kann. Damit konnte aber auch nichts vom Clipboard per Code kopiert werden.
Die Lösung ist dann einfach: zuerst das Bild einfügen, dann auf Readonly setzen.
Dein Tipp war aber entscheidend: (oder ist es ausgegraut)
Jetzt kommt der nächste Schritt: das Bild in den Textfluss einbauen...
Ich verwende .NET Framework 8. Wäre mal interessant, ob es da Unterschiede zu 4 gibt.
Wäre auch interessant, wie du das BMP eingefügt hast. Vielleicht habe ich da einen Fehler?
Sieht so aus, als hätte niemand bisher eine Idee, wie das zu machen ist.
Ich habe inzwischen eine Möglichkeit gefunden, ein Bild in einer RichTextBox darzustellen:
PictureBox NeoPixel = new PictureBox();
NeoPixel.SizeMode = PictureBoxSizeMode.StretchImage;
Bitmap ImageNeoPixel = new Bitmap("NeoPixel.jpg");
NeoPixel.ClientSize = new Size(400,254);
NeoPixel.Image = ImageNeoPixel;
RichTextBoxAufbauanleitung.Controls.Add(NeoPixel);
Damit befindet sich das Bild in der linken oberen Ecke.
Wenn ich jetzt aber einen Text hinzufüge, dann wird der Text hinter das Bild geschrieben, d.h. er startet auch in der linken oberen Ecke.
Wie kann ich die PictureBox an eine beliebige Stelle in der RichTextBox positionieren? Wie kann ich Text um das Bild herumfließen lassen?
Ich glaube zu verstehen, dass durch das Controls.Add die PictureBox genau so ein Kind-Element ist wie der RTF-Text, also parallel zu ihm ist. Ich meine, dass ich die PictureBox nicht an die RichtTextBox, sondern an den RTF-Text anbinden muss.
Wie kann man das machen?
Ich habe in Word eine RTF-Datei mit einem Bild erstellt und wollte dieses in einer RichTextBox darstellen. Die RichtTextBox ignoriert das Bild und stellt nur den Text dar.
Ich habe den Artikel "Insert Plain Text and Images into RichTextBox at Runtime" gelesen, wollte es aber erst einmal mit dem Clipboard versuchen:
Dachte ich, das mag vielleicht am jpg-Format liegen; habe also das Bild in eine Bitmap umgewandelt. Aber auch mit NeoPixel.bmp funktioniert es nicht.
Es ist immer die Paste-Methode die nicht funktioniert.
ich habe ein DGV, in dem ich per Programmierung eine neue Zeile einfüge. (DGV ist gebunden per BindingSource, die wiederum mit einer Liste von Objekten verbunden ist.) Ich stelle dabei sicher, dass in der Zeile nur gültige Daten sind. Der User soll aber die Daten ändern, zumindest einen Namen. Dieser Name darf nur alphanumerische Zeichen, Umlaute, ß und Leerzeichen oder Bindestrich enthalten, sofern diese von den alphanumerischen Zeichen "umrahmt" sind. Die Prüfung dazu führe ich per Regex mit einem entsprechenden Pattern durch. All dies funktioniert soweit.
Wenn der User etwas ändert, dann ist er in der entsprechenden Zelle im Editiermodus. Sobald er die Zelle verlassen will, soll das nur erlaubt sein, wenn seine Änderung die o.g. Forderung erfüllt. Ich habe dazu den CellValidating-Handler bemüht; das funktioniert aber nicht richtig. Der User muss quasi die Zelle verlassen. dann nochmal aufrufen und erst dann beim Verlassen wird die Meldung angezeigt.
ich stelle eine RGB-Farbinformation in einer TextBox als Hintergrundfarbe dar. Um die Farbe (es sind meist helle Farben) besser vom Hintergrund abzusetzen, wollte ich einen dunkelgrauen dicken Rahmen (10 Pixel) um das Rechteck haben. Ich habe aber für die Textbox keine Eigenschaft "Rahmen" gefunden; meine Einstellung ist Borderstyle=Fixed3D. Daher habe ich die Textbox in eine GroupBox (ohne Schrift) mit grauer Hintergrundfarbe getan. Jetzt sehe ich, dass die GroupBox unten und oben je eine helle Linie hat.
Die Einstellungen der GroupBox sind
BackColor: Gray
BackgroundImage: (keine)
BackgroundImageLayout: Tile
FlatStyle: Flat
ForeColor: ControlText
Margin: 0;0;0;0
Padding: 0;0;0;0
Enabled: False
1. Gibt es eine Rahmen-Eigenschaft für Textboxen? (Dann brauche ich keine GroupBox)
2. Kann man die GroupBox ohne die störenden Linien erzeugen?
This content has been retired and may not be updated in the future. The product, service, or technology mentioned in this content is no longer supported.
Also werde ich doch die zugrunde liegende Liste Timings sortieren, es sei denn jemand, der die Grundlagen so richtig versteht (z.B. FZelle), bringt mir die richtige Liste, mit der das dann alles kein Problem ist.
Also bleibt die Frage, wie das gehen soll, wenn ich die richtige Liste nicht nehmen kann. Dazu brauche ich einen Vorschlag; sonst bleibt mir doch nur das BubbleSort.
Das habe ich mir auch schon überlegt, so als Plan B.
Danke, dass du es hier schon dargestellt hast, spart mir etwas Aufwand.
Andererseits ist es ein schwaches Bild von den UI-Entwicklern, ein DataGridView zu entwickeln (was ja an Excel erinnern soll) und dort die Funktionalität des Sortierens (was ich als Basic sehe) so zu machen, dass sie eigentlich nicht in das Gesamtkonzept passt und daher nur mit großer Mühe (wenn überhaupt) zu programmieren ist.
Hallo,
Nichts scheint hier einfach zu gehen.
Ich wollte das DataGridView sortieren: geht aber nur, wenn nicht gebunden.
-> ok ->
Dann versuche ich es mal mit der BindingSource:
private void ComboBoxTimingSortieren_SelectedIndexChanged(object sender, EventArgs e)
{
BindingSourceTiming.DataSource = Timings;
if (BindingSourceTiming.SupportsSorting != true)
{
MessageBox.Show(" no SupportsSorting");
}
switch (ComboBoxTimingSortieren.SelectedItem.ToString())
{
case "Uhrzeit, Led und Relais gemischt":
BindingSourceTiming.Sort = "Uhrzeit ASC";
break;
case "Uhrzeit Led, dann Uhrzeit Relais":
BindingSourceTiming.Sort = "Typ ASC, Uhrzeit ASC";
break;
case "Uhrzeit Relais, dann Uhrzeit Led":
BindingSourceTiming.Sort = "Typ DESC, Uhrzeit ASC";
break;
case "Led Uhrzeit, dann Relais Uhrzeit":
BindingSourceTiming.Sort = "Uhrzeit ASC, Typ ASC";
break;
case "Relais Uhrzeit, dann Led Uhrzeit":
BindingSourceTiming.Sort = "Uhrzeit ASC, Typ DESC";
break;
default:
BindingSourceTiming.Sort = "Uhrzeit ASC";
break;
}
}
Geht auch nicht, da das nicht supported wird. Dazu muss die "zugrunde liegende Liste eine IBindingList sein.
Meine zugrunde liegende Liste ist mit
public List<Timing> Timings;
definiert.
Wie komme ich denn jetzt zu einer IBindingList?
Damit ist zuerst einmal der Fehler weg. Da dieses neue Setzen der DataSource immer passieren soll, habe ich das wieder gelöscht und als ersten Befehl in die DataBindingComplete gesetzt:
Der Erfolg ist nur ein Teilerfolg, weil jetzt die Linq-Sequenzen nicht mehr funktionieren: Das Query wird dadurch einfach überschrieben. Also muss ich mir für das Sortieren etwas anderes einfallen lassen.
Ich bitte um Kommentare, ob ich da auf dem richtigen Weg bin.
Da hast du Recht - ist Blödsinn. Habe ich entfernt.
Aber der Fehler bleibt unverändert.
Ich habe auch noch gesehen, dass sich, wenn 2 Comboboxen unterschiedlichen Inhalts durch den User vertauscht werden, die Liste der Objekte nicht ändert.
Hallo,
kurz bevor mich die Verzweiflung vollständig packt frage ich hier um Hilfe.
In meinem DataGridView (DGV) stelle ich Daten dar, die zeilenweise aus unterschiedlichen ComboBoxen (und damit unterschiedlichen Listen von Objekten stammen. Bei 2 User-Aktionen wird eine Spalte nicht aktualisiert, die Entsprechende ComboBox auch nicht und einzelne Zellen bleiben leer. Ich sehe 2 Aktionen, durch das dies beeinflusst wird:
- Drag & Drop: der User packt eine Zeile und verschiebt sie
- Sortieren: die Zeilen werden ebenfalls verschoben
Das Ganze passiert nur dann, wenn eine ComboBox mit einer anderen unterschiedlichen Inhalts vertauscht wird.
3 Methoden tragen möglicherweise dazu bei: DataBindingComplete
Hallo,
ich habe eine DataGridViewComboBox. Wenn der User den Wert ändert nutze ich das CellValueChaged-Ereignis, um andere Inhalte zu ändern. Das funktioniert auch. Die Änderung kommt aber erst, wenn eine andere Zelle angeklickt wird.
Welches Ereignis kann man nutzen, um die Änderung zu starten, wenn der geänderte Wert in der ComboBox angezeigt wird?
Ich habe gelesen, dass ein DataError auftritt, wenn z.B. Daten von einem Speicher geladen werden und dabei ein Fehler entsteht. Entweder muss dann der Zellenwert korrigiert werden oder die Formatierung muss geändert werden.
Da ja alles richtig angezeigt wird, schließe ich einen Datenfehler aus und vermute einen Formatierungsfehler. Ich habe bisher keinen Formatfehler gefunden und nun folgenden Code geschrieben:
private void DataGridViewTiming_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
if (e.Exception.Message == "Der DataGridViewComboBoxCell-Wert ist ungültig.")
{
object value = DataGridViewTiming.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
if (!((DataGridViewComboBoxColumn)DataGridViewTiming.Columns[e.ColumnIndex]).Items.Contains(value))
{
((DataGridViewComboBoxColumn)DataGridViewTiming.Columns[e.ColumnIndex]).Items.Add(value);
}
}
}
Wirklich zufrieden bin ich damit aber nicht.
Hat jemand eine Idee, wo und wie ich suchen könnte?
Ich will eine im DataGridView eine ComboBox zeilenweise in Abhängigkeit von Werten in einer anderen Spalte füllen. Dazu habe ich bei Form_Load die Liste von Objekten eingelesen und die BindingSource festgelegt.
Im Designer habe ich die Columns 2 und 3 als DataGridViewComboBoxColumn festgelegt.
Schließlich rufe ich das DataBindingComplete-Event auf, wo ich die ComboBoxen zeilenweise befülle. Damit überschreibe ich die Einstellung der Column 3.
erhalte ich das gewünschte Ergebnis, d.h. mein DGV ist so gefüllt wie ich es möchte.
Trotzdem muss es einen Fehler bei der ComboBoxCell geben. Kann mir da jemand helfen?
Irgendwie müsste doch das erste join mit dem ersten where gruppiert werden, und das zweite join mit dem zweiten where. Würde das zweite where sich auf das erste join beziehen, wäre das Ergebnis falsch.
Hallo,
obwohl ich die Doku mehrfach rauf und runter gelesen habe, verstehe ich nicht, was eine BindingList ist und wie sie aufgerufen wird.
Ich habe ein Objekt mit diversen Membern.
public class Timing
{
... Konstruktoren
}
Damit erzeuge ich eine Liste von Objekten
public List<Timing> Timings;
Nun sollte die BindingList eine Alternative zur BindingSource sein, wobei die BindingList wohl eine Teilmenge der BindingSource ist.
Was ist dann mit einem Code
IBindingList source = new BindingList<T>(datasource);
Was ist dann datasource in meinem Fall? Ich bin da komplett verwirrt.
Kann mir jemand das erklären?
Ich wollte das mit einer Linq-Abfrage lösen, aber folgender Code funktioniert nicht:
var timingQuery =
from tq in Timings
join lq in Leds on tq.Nummer equals lq.Nummer
where tq.Typ.Equals(Lichtquelle.Led)
join rq in Relaises on tq.Nummer equals rq.Nummer
where tq.Typ.Equals(Lichtquelle.Relais)
select tq;
BindingSourceTiming.DataSource = timingQuery.ToList();
public class Timing
{
private string _uhrzeit;
public Timing()
{
}
public Timing(int tagminute, Lichtquelle typ, int nummer, BZustand zustand)
{
Tagminute = tagminute;
Typ = typ;
Nummer = nummer;
Zustand = zustand;
}
public int Tagminute
{
get => UhrzeitToTotalmin(_uhrzeit);
set => _uhrzeit = TotalminToUhrzeit(value);
}
public Lichtquelle Typ { get; set; }
public int Nummer { get; set; }
public BZustand Zustand { get; set; }
}
Hallo,
ich habe eine Liste von Objekten, die ich in einem DataGridView (DGV) darstelle. Ich möchte aber in einer Spalte einen berechneten Wert darstellen. Mir ist klar, dass DGV nur darstellt und nicht berechnet. Irgendwo auf dem Weg vom Objekt über die BindingSource muss eine Methode mit dem Berechnungsalgorithmus sein. Ich weiß nicht, wo ich das machen muss.
Kann mir jemand sagen, wie das geht oder wo das dokumentiert ist? Ich dachte, es würde mit Linq gehen, aber da habe ich nicht gefunden wie man eine Methode dort einbaut.