Da wird nichts formatiert. Da übergibst du Start- und Enddatum als DateTime.
this.dgvData.ContextMenuStrip = this.cmsMenu;
Ist sicherlich am einfachsten, nur wird das Kontextmenü zum Beispiel auch dann angezeigt, wenn die Maus sich im Überschriftenbereich befindet. Dann kann man schlecht dem Anwender anbieten 'Datei löschen'.
Zitat msdn
Es wird nachdrücklich empfohlen, das Präfix sp_ nicht im Prozedurnamen zu verwenden. Dieses Präfix wird von SQL Server verwendet, um gespeicherte Systemprozeduren zu bestimmen.
Durch die Verwendung von BindingSource und DataTable schlagen Änderungen an der DataTable direkt auf das Grid durch. Das hast du schon richtig erkannt. Ich hatte auch solche Probleme und konnte sie dadurch lösen, in dem ich vor der DataTable-Aktualisierung die Eigenschaft BindingSource.RaiseListChangeEvents = false gesetzt habe. Dadurch werden die Änderungen nicht durchgereicht.
An geeigneter Stelle (GUI-Thread) musst du dann das Property wieder zurücksetzen und evtl. das Grid refreshen.
Nimm doch das, was es schon gibt. ZoomTrackBarControl von DevExpress.
Vielen Dank für die Antwort und den Gedankenanstoß. Ich werde es in Kürze ausprobieren und berichten.
verwendetes Datenbanksystem: SQL Server 2008
Es ist folgendes Scenario gegeben: Eine typisierte DataTable wird mittels BindingSource an ein DataGridView gebunden. BindingSource.DataSource wird mit dem DataSet verknüpft, BindingSource.DataMember mit dem Tabellennamen der DataTable. Soweit so gut, alles nach Schema F.
Jetzt werden in zyklischen Perioden alle Datensätze der DataTable durchlaufen und für jeden Satz finden umfangreiche Aktionen statt. Das Abarbeiten aller Daten (in etwa 20 Datensätze) wird mittels BackGroundWorker im Hintergrund durchgeführt. Jetzt werden bestimmte Spalten der DataTable aktualisiert, indem einfach die Spaltenwerte neu gesetzt werden. Die Aktualisierung spiegelt sich auch direkt in der DataGridView wieder. Und das ist vermutlich genau mein Problem. Das DataGridView wirft sporadisch je nach Auslastung des Computers eine Exception (System.InvalidOperation: BindingSource kann nicht die eigene Datenquelle sein). Die Exception kommt als MessageBox auf dem Bildschirm, das Programm läuft aber normal weiter. In der MessageBox wird zusätzlich gesagt, man solle das DataError Event des Grid verwenden, um die Message zu ersetzen. Das nützt mir aber nichts, weil es soll ja erst gar nicht zu einer Exception kommen.
Man sagt ja, dass man im Hintergund die GUI nicht aktualisieren kann. Dieses mach ich aber eigentlich implizit durch das Ändern einer DataRow. Diese Änderungen schlagen direkt durch aufgrund von internen Events.
Die Frage ist: Wie kann mann im Hintergrund die Row einer DataTable aktualisieren, welche über DataBinding an ein Control gebunden ist?
die 'DoWork' Methode wird ja vom BackGroundworker durch die Methode 'RunWorkerAsync' angestossen. Du könntest mittels
backgroundWorkerUeberFleet.IsBusy
abfragen, ob der Worker gerade läuft oder nicht. Wenn er nicht läuft, rufst du 'RunWorkerAsync' auf, sonst nicht.
naja, du musst nur die Methode richtig vewenden.
bSServer.Position = bSServer.Find("NameDerSpalte","Arizona");
kommerzielle Lösung von DevExpress (DataGrid)
http://www.devexpress.com/Products/NET/Controls/WinForms/Grid/banded_view.xml
Vielen Dank für die Antwort.
Noch nicht ganz das, was ich benötige, da unter anderem die berechneten Spalten hard coded sind, ich erwarte aber auch keine Musterlösung. Zumindest habe ich jetzt ein paar Gedankenanstöße und komme in dem Projekt weiter.
Die Tabelle hat einen Primärschlüssel, hatte ich ja auch in etwa geschrieben. Primärschlüssel ist ID + Zeitstempel.
verwendetes Datenbanksystem: SQL Server 2008
Ich versuche mich an einer möglichst eleganten Lösung folgender Aufgabenstellung: Es wird eine einzige Tabelle (namens Stromzaehlerwerte) verwendet, die zyklisch alle 10 min mit Werten gefüllt wird. Die Tabelle hat im Prinzip folgenden Aufbau.
Zaehler-ID (int)
Zeitstempel (datetime)
Stand (int)
Zaehler-ID + Zeitstempel ist unique Key. ID verweist auf eine Stammdatentabelle des Stromzaehlers. Im Prinzip schauen die Daten derart aus:
1, 01.08.2009 00:00:00, 1000
1, 01.08.2009 00:10:00, 1010
1, 01.08.2009 00:20:00, 1025
...
1, 01.08.2009 23:50:00, 2000
1, 02.08.2009 00:00:00, 2010
...
usw. für weitere Zaehler und Zeitstempel. Jetzt soll eine Tagesauswertung stattfinden und zwar derart:
Zaehler-ID, Startwert 01.08.09, Endwert 01.08.09, Differenz 01.08.09, Startwert 02.08.09, Endwert 02.08.09, Differenz 02.08.09, ...
für max. 31 Tage. Ich suche nach einer eleganten Lösung mittels SQL, bin aber bisher kläglich daran gescheitert. Ich bin der Meinung, dass man mit einer Pivottabelle lösen müßte, aber irgendwie fehlt mir hier der Ansatz.
Würde mich doch sehr wundern, wenn alle Tabellen, die man über die ComboBox auswählen kann, dieselben Spalten enthalten.
Stimmt, hatte ich vergessen. Erübrigt sich dann aber die Zuweisung von base.BackColor = Color.Red;? Eigentlich nicht, oder?
ob du jetzt
base.BackColor = Color.Red;
schreibst, oder
this.BackColor = Color.Red;
beide Anweisungen verwenden die selbe Variable, wenn BackColor ein Property/Variable der Basisklasse ist. Du solltest aber die zweite Variante benutzen, da sie lesbarer ist.
Vielen Dank für die Antworten und die Denkanstöße. Funktioniert soweit. Das letzte Script habe ich jedoch anpassen müssen (fehlendes NOT). Hier die korrekte Version.
IF EXISTS (SELECT TOP(1) 1 FROM INSERTED) AND NOT EXISTS (SELECT TOP(1) 1 FROM DELETED) --INSERT
BEGIN
END
ELSE IF EXISTS (SELECT TOP(1) 1 FROM INSERTED) AND EXISTS (SELECT TOP(1) 1 FROM DELETED) --UPDATE
BEGIN
END
ELSE IF NOT EXISTS (SELECT TOP(1) 1 FROM INSERTED) AND EXISTS (SELECT TOP(1) 1 FROM DELETED) --DELETE
BEGIN
END
verwendetes Datenbanksystem: SQL Server 2008
In unserer Datenbank werden reihenweise Trigger verwendet, die auf INSERT und UPDATE reagieren. Jetzt muss ich diese auf bestimmte Art und Weise erweitern. Und zwar muss ich erkennen, durch welches SQL-Kommando der Trigger ausgelöst worden ist. Es reicht aus zu erkennen, ob der derTrigger durch ein INSERT oder ein UPDATE ausgelöst worden ist.
Natürlich könnte man einen Trigger schreiben für INSERT ++und ++ einen anderen für UPDATE. Das kommt zunächst einmal nicht in Frage, da ich sonst alle bestehenden Trigger aufteilen müßte.
Hat hier jemand eine Idee.
Ich denk, im Cellpainting sollte das gehen: Dort prüfst du die Zusatzspalte des DataBoundItem, und verwendest die zB dort hinterlegte Color als BackColor der Zelle.
Edit
Also von der Vorstellung wegkommen: Wert geändert - dann zeichnenHin zu: je nach Wert verschieden zeichnen.
Ja, CellPainting funktioniert. Nur schade, dass dieses Event relativ häufig ausgelöst wird, aber es klappt. Vielen Dank für die Antworten und Gedankenanstöße.
Wie "entsprechend verwenden"? Ich denk, die Zellen werden jetzt korrekt markiert?
Das Event, was übrigens gefeuert wird, ist glaub DataTable_RowChanged.
Die Zeilen werden nicht 'markiert'. Dazu müsste ich ja erst mal die richtige Zeile finden. Vielleicht habe ich mich auch schlecht ausgedrückt.
Angenommen ich habe eine DataRow mit drei Zeilen. Für die dritte Zeile mache ich eine Änderung einer Spalte. Die Änderung wird auch direkt in die zugehörige DataGridViewRow des Grid übernommen. Leider wird für das Grid kein Event gefeuert, welches ich benutzen könnte, um jetzt die geänderte DataGridViewRow farblich zu markieren. Ich habe diverse Events ausprobiert, auch das RowStateChanged Event.
Vielen Dank für die Antworten.
Das mit der zusätzlichen Spalte ist eigentlich eine gute Idee. Das habe ich auch umgesetzt. Wenn ein entsprechender Satz geändert wird (also die DataRow), wird das Grid auch automatisch aktualisiert. Jedoch wird mit der Änderung kein Event im DataGridView ausgelöst, was ich entsprechend verwenden könnte. Nach meinem Verständnis sollte zumindest das Event 'CellValueChanged' gefeuert werden. Das wird jedoch bei mir nur ausgelöst, wenn der Anwender direkt in der Zelle editiert.
verwendetes Datenbanksystem: SQL Server
Ich habe gerade ein Brett vorm Kopf. Ich verwende folgendes: DataGridView, BindingSource, typisiertes DataSet
Das typisierte DataSet enthält genau eine Tabelle. Mittels DataSource und DataMember wird das DataSet und die Tabelle mit der BindingSource verbunden. Die BindingSource ist DataSource des DataGridView. Das funktioniert auch alles soweit; das Grid wird richtig gefüllt.
Meine Aufgabe ist, in zyklischen Perioden alle Datensätze zu durchlaufen und je Datensatz eine Aktion auszuführen. Hierzu iteriere ich über die DataRows des DataSets. Auch alles kein Problem. In bestimmten Fällen soll der aktuell bearbeitete Datensatz im DataGridView farblich markiert werden. Hierzu muss ich aber die entsprechende Row im DataGridView finden und finde hierzu keine passende Methode. Wie ermittel ich zu einer DataRow die gebundene Datenzeile des DataGridView?
mySettings = new MySample.Properties.Settings();
lng_ar_time[1] = mySettings.lng_timer1;
Da kann wie das sehe nichts herauskommen. Du hast ein Settings Objekt erstellt mit vermutlich initialen Werten.
Ich denke, du solltest es mal auf diese Art und Weise probieren, da du wohl Benutzer- bzw Anwendungseinstellungen abfragen möchtest.
lng_ar_time[1] = Properties.Settings.Default.lng_timer1;
Vielen Dank für die Antworten. Das Thema ist für mich gelöst. Die genannte Artikelserie, die ich zuvor nicht gefunden habe, beschreibt eine Lösung.
verwendetes Datenbanksystem: SQL Server 2005/2008
Ich muss ein SQL-Statement nach folgendem Schema absetzen:
SqlCommand cmd = new SqlCommand("SELECT * FROM Artikel WHERE ArtikelNr IN (@ListeArtikelNr)", ConnString);
cmd.Parameter.Add(new SqlParameter("@ListeArtikelNr", GetListeArtikelNr()));
Das Absetzen des Kommandos liefert keinen Fehler, aber auch keine Ergebnisse, obwohl Daten vorhanden sind. Wenn ich die Artikelliste direkt in das Sql-Statement einfüge ohne SqlParameter klappt alles. Es soll ja im allgemeinen SqlParameter verwendet werden, in diesem Fall scheint es aber nicht zu funktionieren. Mache ich etwas falsch oder gibt es hierfür eine ideale Lösung.
z.B. so
Properties.Settings.Default.MyParameter
MyParameter entspricht dann einem Eintrag in den 'Einstellungen'.
Dir fehlt die Zuweisung der DataTable an die BindingSource nach dem Füllen der Tabelle.
dataBindingSource1.DataSource = table;
Evtl. wird in deinen Drag & Drop Methoden eine Exception geworfen, die aber Windows intern abhandelt. Ich würde mal entsprechende Methoden mitttels try / catch-Blöcken kapseln, um obiges zu checken.
Das GridControl von DevXpress scheint ASP.NET zu sein, oder habe ich mich da verschaut? Ist aber auch nicht so wichtig, da eine kostenlose Version eher geeignet wäre.
Wenn du wirklich daran interressiert bist, musst du nach der XtraGrid Suite suchen, welches das GridControl bzw. XtraGrid enthält.
Wenn's was kosten darf, dann ist das GridControl von DevXpress genau das, was du suchst. Die Gruppierung bekommst du ohne geschriebene Codezeile automatisch dazu.
Benutze doch zwei einzelne Prüfungen für Double und Byte:
double dDouble;
bool bIsDouble = Double.TryParse("1234", out dDouble);
Für Byte genauso.
Da bin ich ja erleichtert, dass zumindest einer auch dieses Verhalten als Bug ansieht.
Was den Fix des Bugs angeht: Meiner Meinung nach eine gute und akzeptable Lösung. Vielen Dank.
Unten oben genannten Bedingungen ist wohl das Problem, dass das 'ValueChanged' Event erst nach dem 'Validating' Event geworfen. Daher rührt der alte Wert des Controls. Durch den Fokuswechsel erzwingt man das Werfen von 'ValueChanged'.
Gibt es keinen, der ein derartiges Problem hat. Es sollte doch eigentlich jeden hier betreffen, der den DateTimePicker verwendet und gleichzeitig das Validating Event benutzt.
Ich habe ein Problem mit dem DateTimePicker.
Ich benutze das Validating Event zum Prüfen von korrekten Eingaben. Soweit so gut. Jedoch gibt es Situationen, da wird das Event geworfen, aber der 'Value' wird nicht aktualisiert, d.h. dort steht noch der alte Wert vor der Änderung. Somit ist die Prüfung natürlich umsonst, da sich eigentlich nichts geändert hat.
Dieses passiert nur dann, wenn
Kennt jemand dieses Problem und wenn ja, gibt es dafür eine Lösung? Ich benutze das Framework 2.0. Das Format des DateTimePicker ist auf 'Short' eingestellt.
Hat einer eine Idee? Interessant zu wissen wäre auch, ob ihr den Bug nachstellen könnt.
Die Methode ContainsKey() berücksichtigt anscheinend nur die Nodes im aktuellen Knoten. Insofern musst du wohl eine eigene Methode implementieren, die rekursiv alle Knoten durchläuft. Ungefähr so:
private bool ContainsKey(TreeNodeCollection nodes, string strKey)
{
if (nodes != null)
{
if (nodes.ContainsKey(strKey)) return true;
foreach (TreeNode node in nodes)
{
if (ContainsKey(node.Nodes, strKey)) return true;
}
}
return false;
}
Die Methode rufst du dann so auf:
if (!ContainsKey(viewPCTView.Nodes, domain.Name))
BTW: Benutze folgende Methode zum Hinzufügen von Knoten:
node = viewPCTView.Nodes.Add(domain.Name, domain.Name);
So wird der Key und der Name gleichzeitig gesetzt.
Guck dir mal das 'Name' Property von den erzeugten Knoten an. Denn darauf prüft ContainsKey(). Ich vermute mal, dass TreeView.Node.Add("string") dieses Property nicht setzt.
Defaultvalues von Properties müssen immer an zwei Stellen definiert werden. Zum einen über das Attribut 'DefaultValue', un zum anderen über den Initialwert des Propertymembers (in deinem Fall 'this._panelFooter.Visible'). So sollte es funktionieren.
public DeineForm()
{
InitializeComponent();
this._panelFooter.Visible = false;
}
[DefaultValue(false)]
public bool EnableFooter
{
get
{
return this._panelFooter.Visible;
}
set
{
this._panelFooter.Visible = value;
}
}
if (c is System.Windows.Forms.Button)
{
;
}
Hallo D.Follmann,
Die vertikale Scrollbar an den rechten Rand positionieren und in der Größe so einstellen, wie du sie brauchst. Anchor einstellen auf Top, Right, Bottom.
Die horizontale Scrollbar an den unteren Rand positionieren und ebenfalls in der Größe einstellen. Anchor einstellen auf Left, Right, Bottom.
Nicht mit Dock arbeiten.
Das Ergebnis kannst du dann sofort sehen, wenn du im Designer die Größe deines Usercontrols änderst.
Versuch es mal so.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace FormTimer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Enabled = false;
}
private void timer1_Tick(object sender, EventArgs e)
{
// send email
}
private void button1_MouseDown(object sender, MouseEventArgs e)
{
timer1.Start();
}
private void button1_MouseUp(object sender, MouseEventArgs e)
{
timer1.Stop();
}
}
}
timer1 und button1 sind entsprechend deine Controls auf der Form. Im Timer stellst du ein, in welchem Zeitintervall die Mail verschickt werden soll. Vergiss nicht, die 3 Events zu abonnieren.
Eine einfache wie auch geniale Idee. Die Sache hat nur einen kleinen Haken. Ich habe noch keine Zeichenmethode gefunden, die einen Border im gleichen Style zeichnet wie die TextBox.
Ich habe das Problem jetzt so gelöst, dass ich als Untergrund eine weitere TextBox verwende, die nicht editierbar ist und entsprechende Farben eingestellt hat. Vielleicht nicht die sauberste Lösung, aber es funktioniert.
Danke an allen Usern, die hier gepostet haben.
Gruss tabstop
Hört sich ganz gut an.
Einfach die TextBox bzw. den Text ownerdraw zeichnen und aufhören wenn der Button vor der Tür steht.
Mir stellt sich die Frage, welche Methode dazu überschrieben werden muss, bzw. wie man den Text der Textbox selber zeichnen kann. Meine erste Idee dazu war, die OnPaint-Methode zu überschreiben, jedoch habe ich festgestellt, dass diese Methode dann gar nicht aufgerufen wird.
Über ein oder zwei Stichpunkte hierzu wäre ich sehr dankbar.
vielen Dank für die Antworten.
Ok, anscheinend führt kein Weg daran vorbei, ein UserControl zu verwenden. Wenn jetzt warum auch immer die Vorgabe ist, dass der Button innerhalb des Controls platziert werden muss, wie erreicht man es, dass der Text nicht vom Button verdeckt wird. Meinetwegen auch durch geschickte Kombination mehrerer Controls.
Nach aussen hin sollte das Control für den Anwender ausschauen wie eine gewöhnliche Textbox (plus Button natürlich).
Daran habe ich auch schon gedacht. Das Problem hierbei ist jedoch, dass das zu erstellende Control wie die TextBox auch aus der Toolbox auswählbar sein soll. Wenn das UserControl die Basis ist, sieht man nur die Eigenschaften und Methoden des UserControls und nicht die der TextBox (z.B. wäre dann die 'Text'-Eigenschaft nicht sichtbar, usw.). Sämtliche Eigenschaften, Methoden, ... müssten dann zu Fuss bekannt gemacht werden.
Ausserdem sollte der Button innerhalb des Controls liegen und nicht ausserhalb.
Hallo,
ich habe folgendes Problem:
Ich versuche eine TextBox in dem Sinne zu erweitern, dass sie zusätzlich einen anclickbaren Button enthält (ähnlich dem Textbox FormatString einer ComboBox im Property-Fenster). Das ganze bekomme ich auch hin, nur das Problem ist, dass bei einer Texteingabe der Text bei entsprechender Länge hinter dem Button verschwindet und das ist irgendwie unschön. Hat jemand hierfür eine Lösung oder Tipps.
Anbei mein bisheriger Lösungsansatz:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace NewTextBox
{
public class MyTextBox: TextBox
{
private System.Windows.Forms.Button button1;
public MyTextBox()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.button1.Location = new System.Drawing.Point(this.Size.Width - 16 - 3, 0);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(16, 16);
this.button1.TabIndex = 0;
this.button1.Text = "...";
this.button1.UseVisualStyleBackColor = true;
this.Controls.Add(this.button1);
this.ResumeLayout(false);
}
}
}