Hast du es mal mit MouseDown probiert? Und dort kannst du dir ein Flag setzen und merken ob die rechte Maustaste gedrückt wurde, und entsprechend im MouseUp event darauf reagieren.
Du gehst damit niemand auf den Geist :-)
Ich geb dir voll und ganz recht, für Tabellendarstellung ist das DGV einfach besser geeignet, das ListView ist zwar leichter zu "handeln", aber das DGV dafür deutlich mächtiger. Nicht zu vergessen die Performance, die beim DGV gegenüber dem ListView auch nicht unerheblich ist.
Doch es geht ohne schleife! Prüfe doch mit Regex auf den Anfang des Strings und dann nur Digits. Das müsste also auch gehen.
public int atoi(string source)
{
Regex regex = new Regex(@"^([-\d]\d*)");
Match match = regex.Match(source);
if (string.IsNullOrEmpty(match.Value))
{
throw new ArgumentException("The string does not contain digits.");
}
return Int32.Parse(match.Value);
}
am rande: Die textboxen die ich setzen will sind zu diesem zeitpunkt unsichtbar, könnte es damit zu tun haben?
Nein du kannst generell keine Steuerelemente von einen anderen Thread, als den der sie erstellt, hat updaten. Benutze dazu immer ein Delegate. Schau dir auch mal den Thread an, sollte dir helfen.
Das stimmt, aber da du schreibst ich werde "aber" meine Lösung weiter benutzten, schließe ich daraus das deine Lösung Vorteile hat. Lass uns an diesen Vorteilen teilhaben.
Schau ob das bild richtig gesetzt wird. Am einfachsten du lädst es mal schnell in eine PictureBox und schaust ob es angezeigt wird. Wenn du die ListView im Detailed view anzeigen möchtest, also z.B. mit mehreren Spalten, dann musst du die Bilder selber zeichnen. HAb mal ein kleines Beispiel angehängt.
public class ImageListView : ListView
{
private ImageList m_imageList;
public ImageListView()
{
this.OwnerDraw = true;
}
public ImageList DetailImageList
{
get
{
return this.m_imageList;
}
set
{
this.m_imageList = value;
}
}
protected override void OnDrawItem(DrawListViewItemEventArgs e)
{
base.OnDrawItem(e);
}
protected override void OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e)
{
base.OnDrawColumnHeader(e);
e.DrawBackground();
using (SolidBrush brush = new SolidBrush(this.ForeColor))
{
e.Graphics.DrawString(e.Header.Text, this.Font, brush, e.Bounds.Location);
}
}
protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
{
base.OnDrawSubItem(e);
e.DrawBackground();
using (SolidBrush brush = new SolidBrush(this.ForeColor))
{
e.Graphics.DrawString(e.SubItem.Text, this.Font, brush,
e.Bounds.Location.X + this.DetailImageList.Images[0].Width,
e.Bounds.Location.Y);
e.Graphics.DrawImage(this.DetailImageList.Images[0],
e.Bounds.Location.X,
e.Bounds.Location.Y);
}
}
}
Es wird noch keine Selction und Focus beachtet. Auch müsstest du die SubItem Klasse ableiten und ihr ein ImageIndex verpassen sodass du jeweils das richtige Image zeichnest.
Werde aber meine eigene weiterbenutzen und nur auf "Rectangle rect = this.GetTabRect(i);" zurückgreifen.
Aber du hattest doch gar keine eigene Lösung, wieso dann also weiterbenutzen? Unsere (die von ErfinderDesRades und mir) funktioniert doch einwandfrei, was gibt es daran auszusetzen?
Das ist mir schon klar das ein Koordinatensystem wie man es aus dem Matheunterricht kennt in Abzissenrichtung nach oben wächst. Aber wenn man den Mittelpunkt von oben Links in die Mitte verlagert, dann ist es nun mal so wie ich beschrieben habe.
Dann hast du das aber meiner Meinung nach falsch beschrieben. Du hast ein Koordinatensystem das bei 0,0 nach oben wächst. Wenn du aber einen Punkt verschiebst, so wie du das erklärt hast, dann ist der obere linke Punkt im Ordinate sowie Abzisse negativ, oder hab ich da einen Denkfehler drin...
Das umrechnen ist doch nicht schwer! Ein paar Mathe Grundrechenarten und fertig.
Daher wenn du ein Punkt hast Bsp. (30, 40) und du willst den (0,0) Punkt in den Mittelpunkt schieben und wissen wo der (30, 40) jetzt liegt musst du doch nur
Point p = new Point(30 - this.Width / 2, 40 - this.Heigth / 2);
schreiben. War das wirklich so schwer oder hab ich dich einfach nur falsch verstanden?
Das beantwortet meine Frage nicht. Was passiert wenn du den Font des NumericUpDown Controls auf den von dir gewünschten setzt? Das es beim Label klappt spielt hierbei keine Rolle, ich möcht wissen was passiert wenn du es beim NUD Control äquivalent implementierst.
ich hab dir mal ne Lösung gepostet, die ist meines Erachtens nach gar nicht schwer ist daher leicht zu verstehen ist. Du hängst dich an das MouseClick Event und schaust welcher Button geclickt wurde. Danach überprüfst du ob der User ein TabPage (Reiter) gekickt hat. Ist dies der Fall dann öffnest du ein ContextMenu wobei du die Tabpage gleich mit an die TagProperty hängst. Danach musst du im OnClick des MenuItems nur noch die Tabpage removen. Und fertig!
public class ClickableTabControl : TabControl
{
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseClick"/> event.
/// </summary>
/// <param name="e">An <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
protected override void OnMouseClick(MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
for (int i = 0; i < this.TabCount; i++)
{
if (TabPageClicked(e.Location, i))
{
ContextMenu menu = new ContextMenu();
MenuItem item = new MenuItem("Close", new EventHandler(CloseClick));
item.Tag = this.TabPages[i];
menu.MenuItems.Add(item);
menu.Show(this, e.Location);
}
}
}
base.OnMouseClick(e);
}
/// <summary>
/// Closes the tabpage the user specified.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void CloseClick(object sender, EventArgs e)
{
MenuItem item = sender as MenuItem;
if (item != null)
{
TabPage page = item.Tag as TabPage;
if (page != null)
{
this.TabPages.Remove(page);
}
}
}
/// <summary>
/// Return true if the tabpage which with the given index was clicked.
/// </summary>
/// <param name="point">The point.</param>
/// <param name="i">The i.</param>
/// <returns></returns>
private bool TabPageClicked(Point point, int i)
{
Rectangle rect = this.GetTabRect(i);
return rect.Contains(point);
}
}
Dein Problem kann ich nicht nachvollziehen. Man kann auf jeden Fall Controls per Designer hinzufügen und im nachhinein Controls per Code. Man darf dies nur nicht im Designer Code tun.
Und wenn du wie Herbivore bereits gesagt hat die Controls auch in die Groupbox einfügst dann sind die auch relativ zu Groupbox.
public Form1()
{
InitializeComponent();
InitializeControls();
}
public void InitializeControls()
{
//here you can add what ever you want
}
public void InitializeComponent()
{
//but not here
....
}
Das stimmt nicht ganz! Und zwar ist das OnColumnWidthChanging Event dafür da mitzubekommen wenn der User dabei ist die Breite zu ändern. Daher wenn du dort
e.Cancel = true;
schreibst, dann wird einfach nur nicht die neue breite gezeichnet. Wenn du nun noch das OnColumnWidthChanged Event abfängst kannst du dort einfach die Breite zurück setzen.
foreach (ColumnHeader column in listView.Columns)
{
column.Tag = column.Width;
}
So find ich es akzeptabel. Ich fand nur die Lösung mit der MessageBox komisch. Jedesmal wenn der USer die Column Resizen will blobt eine MessageBox auf. In wie weit die Zeile
Also mir kommt es vor als ob dir die Grundlagen fehlen. Du weist anscheinend nicht wie man mit Datenbanken umgeht, bzw was ein DataSet und Co. ist.
Dabei hat dir juetho alle nötigen Informationen gegeben. Die ignorierst du aber und versuchst die Arbeit auf uns abzuwelzen.
Wir helfen dir gern, aber du musst 1tens selber was dafür tun, und 2tens KONKRETE Fragen stellen, und nicht
Zitat
aber ich weiß einfach nicht wie ich das programmieren muss
Ich würde das Control ableiten und selber umbauen, also z.B. das OnPaint überschreiben. Dort kannst du dann selber die Zahlen zeichnen und die Digitale Schrift einsetzten.