Laden...
Avatar #avatar-1693.jpg
citizen.ron myCSharp.de - Member
Selbst. Software-Architekt Frankfurt / Main Dabei seit 23.07.2005 432 Beiträge
Benutzerbeschreibung

Forenbeiträge von citizen.ron Ingesamt 432 Beiträge

21.04.2007 - 09:13 Uhr

hallo zusammen,

hab´s inzwischen herausbekommen; hier die lösung, falls zukünftig jemand mal ein objekt in ein XML Datenfeld serialisieren möchte.


// Datenzugriffe
   BindingSource bds = GetBindingSource("meineDatenquelle");
   DataRowView viewRow = (DataRowView)bds[bds.Find("Kriterienspalte", einKriterium)];

// Serialisierer erstellen
   XmlSerializer serializer = new XmlSerializer(typeof(meinObjekt));

// StringWriter erstellen! denn es soll ja nicht in eine Datei geschrieben werden
   StringWriter writer = new StringWriter();

// Serialisieren...
   serializer.Serialize(writer, meinObjekt);

// ...und das Ergebnis aus dem Writer in das gewünschte Datenfeld eintragen
   viewRow["zielSpalte"] = writer.ToString();

// Änderungen in der BindingSource übernehmen
   bds.EndEdit();

und falls man es auch zur Deserialisierung verwenden möchte, geht das so:


if (viewRow["zielSpalte"] != DBNull.Value) try
{
   StringReader reader = new StringReader(viewRow["zielSpalte"].ToString());
   XmlSerializer serializer = new XmlSerializer(typeof(meinObjekt));
   meinObjekt = serializer.Deserialize(reader) as meinObjekt;
}
catch {}

viel erfolg
ron

18.04.2007 - 14:19 Uhr

@herbivore,

naja, weil der deserialisierungskonstruktor ja eine vorgeschriebene signatur hat.

beim aufruf würde also ein für meine zwecke unvollständiges objekt zurückkommen.

mein eigentliches objekt wird aber über einen microkernel mit völlig anderer signatur erzeugt und soll eben wie gesagt nur ein paar eigenschaftswerte über die deserialisierung ergänzt bekommen.

hab mich hier mal reingelesen, klingt aber ein bisschen zu kompliziert:
http://www.microsoft.com/germany/msdn/library/net/FortgeschritteneThemenDerNETSerialisierung.mspx?mfr=true
ziemlich weit unten wo es um **ISerializationSurrogate **geht

was meinst Du?

gruß
ron

18.04.2007 - 13:12 Uhr

hallo leute,

ich habe binär einige objekteigenschaften in ein varbinary datenfeld einer tabelle serialisiert.
das geschieht über angepasste serialisierung:


public void GetObjectData(SerializationInfo info, StreamingContext context)
{
   info.AddValue("DisplayFlags", _DisplayFlags);
   info.AddValue("Selection", _SubView.Selection);
   info.AddValue("HiddenGridColumns", _DataGrid.HiddenColumns);
}


da es sich hier ja aber nur um ein paar selektive eigenschaften des gesamten objekts handelt, stellt sich mir die frage, wie deserialisiere ich eigentlich diese information in ein bestehendes objekt?
bei der deserialisierung will ich ja mit einem eigenen konstruktor (kein Deserialisierungs-Konstruktor) das objekt erzeugen und dann **ergänzend eine deserialisierung **für **einige eigenschaften **vornehmen.

wenn ich jetzt also der teilserialisierten klasse z.B. nachstehende methode hinzufüge:


public void SetObjectData(SerializationInfo info)
{
   _DisplayFlags = (eDisplayFlags)info.GetByte("DisplayFlags");
}

dann weiss ich jetzt aber nicht weiter, denn woher kommt die SerializationInfo, mit der ich von aussen diese Methode aufrufen könnte?

danke für eure hilfe

ron

18.04.2007 - 10:18 Uhr

hallo helferleins!

ich würde gerne ein objekt mit angepasster serialisierung (also eine ISerializable-Implementierung) in ein Datenfeld einer SQL server 2005 Tabelle schreiben.

folgender ansatz klappt nicht (z.B. bei neuen Datensätzen, die ich anlege, weil der stream nicht über ein DBNull value erzeugt werden kann:


   DataRowView viewRow;
   BindingSource bds = GetBindingSource("USERVIEW");
   viewRow = (DataRowView)bds.AddNew();
   viewRow["RecordID"] = Guid.NewGuid();
// Create a stream on column [XML]
   MemoryStream mStream = new MemoryStream((Byte[])viewRow["XML"]);  
   XmlSerializer serializer = new XmlSerializer(typeof(IView));
   serializer.Serialize((mStream, view);

danke für eure hilfe

gruß
ron

17.04.2007 - 15:28 Uhr

convert(varchar, meineDatumsspalte, 104)

15.04.2007 - 18:45 Uhr

hi coder

Habs auf die schnelle als n:n Beziehung realisiert, aber ich denke, das ist nicht die optimale Lösung.

warum soll das nicht die optimalste lösung sein?
in einer relationalen datenbank sind relational abgelegte daten das performanteste, was du machen kannst, zumal wenn es nur kleine informationseinheiten wie integers sind.

das als objekt oder irgendwie codiert abzuspeichern und zur laufzeit wieder auseinanderzuklamüsern ist immer der schlechtere weg. erst recht, wenn du danach suchen willst.

jedenfalls imh

gruß
ron

15.04.2007 - 17:47 Uhr

hi netblade,

meine technik basiert wie gesagt darauf, dass ich ein attribut in das tag jedes knotens lege, das ihn eindeutig identifiziert (z.b. den primärschlüssel des eintrags in der datenbank, das ihn eindeutig kennzeichnet.

diese spalte ist im datagridview ebenfalls vorhanden; wenn sie nicht optisch gebraucht wird, ist ihre eigenschaft visible=false.

das ereignis, das für die synchronisation sorgt, ist bei uns das ereignis AfterSelect der treeview. Dort ist aus den TreeViewEventArgs e.Node der aktuell gewählte Knoten.

das ereignis sucht den passenden eintrag im datagridview (hier dgv genannt) mit:


foreach (DataGridViewRow row in dgv.Rows)
{
   if ((Guid)row.Cells["RecordID"].Value == e.Node.Tag)
      if (!row.Selected) row.Selected = true;
}

hierbei ist im Beispiel "RecordID" der Name der Spalte, in der nach dem Tag-Value gesucht wird.

alternativ dazu könnte man auch in der dem datagridview zugrundeliegenden BindingSource direkt die Position setzen. Dazu verwendet man die Methode Find() und ihren Rückgabewert als Positionsindex:

((BindingSource)dgv.DataSource).Position = ((BindingSource)dgv.DataSource).Find("RecordID", e.Node.Tag);

Da das DataGridView an der BindingSource "hängt", reagiert es auch auf dessen Positionsänderung.

Letzteres ist bei vielen Datensätzen der bessere Weg, da kein Schleifendurchlauf durch alle Einträge durchlaufen muss.

hth
gruß
ron

15.04.2007 - 14:48 Uhr

hi bionic

arbeite (ausschließlich!) auf meinem dell xps MXG061

da ist dann auch alles drauf: vs2005, vb 6.0, office 2003 prof., sql server 2000, sql server 2005, mssqlexpress, visio, project, ftp clients, etc.
sprich: eierlegende wollmilchsau... 🙂

der grund war einfach, dass ich oft auch beim kunden vorort programmiere und daher "alles" dabei haben möchte.
aus diesem grund habe ich mir als software noch MobileNetSwitch angeschafft; damit klinke ich mich mit verschiedenen profilen in die netze meiner kunden vorort ein.

würde es nie wieder anders machen - ich bin sehr zufrieden.

leistungsmerkmale:
2g arbeitsspeicher, centrino duo mit 2g taktung, 80gb festplatte, dvd brenner, 6xUSB, smartcardreader, bluetooth, etc., windows xp professional als os

ich kann allerdings dringend empfehlen,
a) ein zweites ladegerät anzuschaffen, damit man eines immer zuhause lassen kann
b) ein kabelloses desktop (hier: logitech dinovo) anzuschaffen

übrigens kann ich DELL nur wärmstens empfeheln, das preis leistungs-verhältnis ist nicht zu schlagen und der service ist ausgezeichnet!

hth
gruß
ron

15.04.2007 - 14:01 Uhr

hi steven,

mit data source im connection string ist der server gemeint; hast du mssql express auf dem gleichen rechner installiert, muss dort also stehen:

".[Instanzname]"

wobei bei SQL Express der Instanzname meit "SQLEXPRESS" ist.

hth
ron

15.04.2007 - 11:50 Uhr

hi webseal,

was zu dem von den anderen gesagten ausserdem geht, ist ein ganzes formular in ein anderes formular einzufügen:


Form childForm = new myForm()
this.ViewPanel.Controls.Add(frm);

dadurch löst du unabhängig von dem modularen charakter der anwendung auch die tatsache, dass es nicht notwendigerweise panels sein müssen, in denen sich deine funktionalen control gruppen befinden.

dabei musst du nur beachten, dass das eingebettete form die properties toplevel und dock setzt:


this.TopLevel = false;
this.Dock = DockingStyle.Fill;

gruß ron

15.04.2007 - 11:44 Uhr

hi stf-dir,

vielleicht wäre in deinem fall eine datagridview mit selectionmode=fullrowselect und einer textbox mit multiline=true als anzeigeelement geeigneter?

gruß
ron

11.04.2007 - 14:51 Uhr

hi bernd

Denn ein GUID sagt ja nichts aus darüber ob ein Datensatz schon vorhanden ist.

nee, is klar, ein datentyp sagt niemals etwas über "schon vorhanden oder nicht" aus, sondern die eigenschaft einer spalte, primärschlüssel zu sein.

und auch ein GUID kann eben als Primärspalte eingesetzt werden, was bei merge replikation bspw. sinnvoll ist.

gruß
ron

11.04.2007 - 13:02 Uhr

hi shabi

du kannst den schlüssel höchstens zu einer zeichenkette zusammenfügen und vergleichen, ansonsten musst du ihn getreent betrachten.

deshalb ist ein "breitgetretener" primärschlüssel auch kein gutes design.

wenn du einfluss auf die datenbank nehmen kannst tu´s und verpass den tabellen einen (künstlichen) primärschlüssel als GUID oder zähler (int).

gruß
ron

10.04.2007 - 19:44 Uhr

hi dragon

iss zwar ein bissi brutal aber man kann ja xp_cmdshell im trigger aufrufen. 😉

du müsstest die halt n konsolenprogramm schreiben, dem du dann vielleicht sogar noch argumente mit auf den weg geben kannst.

hier ein bsp.:

CREATE TRIGGER trg_i_Datei
   ON  dbo.DATEI
   AFTER INSERT
AS 
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

-- Insert statements for trigger here
   declare @s varchar(20)
   select @s = Kennung from inserted

   set @s = 'c:\temp\kannweg.cmd ' + @s

   exec master.dbo.xp_cmdshell @s

END
GO

wenn ich es richtig in erinnerung habe, muss man aber der sql serverinstanz oder der db noch irgendwo sagen, dass erweiterte SP´s oder command shell aus triggern heraus erlaubt sind (kann mich aber irren...)

gruß
ron

09.04.2007 - 12:45 Uhr

hi simon

eigenschaften des projekts, registerlasche "Anwendung", Schalter "Assemblyinformationen...", Option "Anwendung COM-sichtbar machen"

gruß
ron

06.04.2007 - 16:09 Uhr

hi cullmann,

Meine frage ist jetzt: Warum sollte ich wieder auf das interface casten (ICompressible icDoc = doc as ICompressible; ) wenn ich alle Methoden doch direkt über die doc instanz ansprechen kann.

ja schon, aber da du die variable doc ja nicht über einen activator oder eine assembly direct aus einem interfacetyp erzeugt hast, weißt du zur laufzeit ja gar nicht, ob die variable doc die fähigkeiten dieses interface auch wirklich implementiert.

in anderen worten: wenn du zur laufzeit eine variable kfz als fahrzeug initialisierst, weisst du noch lange nicht, dass es ein mähdrescher ist und über die fähigkeit Mäh() verfügt.... 😉

Ausserdem finde ich offengesagt eleganter, statt auf != null zu prüfen, die bedingung gleich zu formulieren als:

if (doc is IStorable)...

gruß

ron

06.04.2007 - 16:01 Uhr

hi philipp

die fragestellung ist ein bissi unpräzise - willst du jetzt excel oder nur "a la excel"??

wenn du excel willst, bietet die das objektmodell von excel bzw. vsto. die geeigneten eigenschaften an mit bspw.

Selection.Cells[3, 3]

willst du nur a la excel dann... tjy dann stell deine frage nochmal mit dem gewünschten ziel; was darf´s denn sein? sql server? access? oracle?

oder vielleicht nur eine DataTable in einem DataSet?

und wenn du´s nur darstellen und nicht speichern willst würde vielleicht schon ein datagridview reichen, dass auf einer bindingsource operiert die wiederum nur mit deiner liste in verbindung gebracht werden müsste.

gruß

ron

06.04.2007 - 15:48 Uhr

normalerweise ist dein datagrid mit einer bindingsource verbunden.

es dürfte schon reichen, das property position dieser binding source auf den gewünschten eintrag zu setzen.

grundsätzlich würde ich aber mal überdenken, ob das alles so der richtige weg ist, denn in einer binding source bzw. im datengitter ist die sortierung ja stark abhängig von dem, was der benutzer so mit dem datengitter anstellt... 🙂

ruß

ron

05.04.2007 - 07:44 Uhr

hi bär,

nichtmal access selbst bietet für die gesamte datenbank den befehl "speichern unter". da wirst du wohl auch unter c# eine dateikopier-operation durchführen müssen.

das versehen mit einem passwort geschieht in access über "kennwort festlegen". dieser befehl ist über die vsto (die ja letztlich nur das vba objektmodell kapselt) erreichbar.

gruß
ron

05.04.2007 - 07:41 Uhr

hi andreas,

die combobox hat für diesen zweck die eigenschaften ValueMember (=geschriebener Wert) und DisplayMember (gezeigter Wert).
diese beziehen sich auf die binding source der combobox (also auf ihre eigene datenquelle)

die databindings der combobox arbeiten wie bei anderen steuerelementen auch. die gebundene eigenschaft sollte dann SelectedValue sein.

gruß
ron

01.04.2007 - 13:26 Uhr

hi markus,

also, die vierte überlegung ist die beste 😉

darüberhinaus haben wir unser framework so ausgelegt, dass zu jeder select stored procedure die passende update/insert prozedur existiert.

es gibt also bspw. eine SP namens udp_s_Kunde für das select.
für update UND (!) insert gibt es eine udp_u_Kunde.
diese entscheidet selbsttätig, ob es den gesuchten eintrag schon gibt (=>where klausel) oder ob er noch nicht vorhanden ist (=>insert statement)

so bekommt unsere klasse zur laufzeit die erzeugung des insert und update command hin, indem sie in beiden fällen nur noch das "s" (wie "select") in "u" verwandelt (wie "update")

diese klasse heisst "BusinessContext" und ist einerseits die implementierung eines interface "IBusinessContext" und andererseits die basisklasse aller mit daten operierender klassen.

Das hat den Vorteil es ist egal welches Objekt ich übergeben der SELECT paßt für alle
Objekte die so aufgebaut sind wie die Kunden Klassen.

unser business context baut diesen vorteil also u.a. dahingehend aus, dass keine select/insert/update-commands irgendwie in der endklasse (Kunde, Person, Dokument, etc.) bekannt sind und die datenbeschaffung und -aktualisierung nur auf der datenbankseite geregelt wird.

hth

ron

01.04.2007 - 09:08 Uhr

hi shorty

sollen ergebnisse der aggregatfunktionen selbst wieder als kriterien verwendet werden, brauchst du dazu die HAVING klausel nach der gruppierung:


select 
   sum(dauer)
from 
   sitzung
where 
   (id = 66) 
group by 
   month(beginn)
having 
   sum(dauer) > 250

gruß
ron

31.03.2007 - 22:39 Uhr

hi markus,

mal die "kurze" antwort vorweg:
ich würde dem formular nicht die tabelle angeben, also wäre der generic aufruf imh der bessere.

jetzt die lange antwort 😁
wenn du schon "hartcodiert" in die klasse kunde reinschreibst, dass es bei der pk-spalte um "id" geht, die ein uniqueidentifier ist etc. warum machst du das nicht gleich als readonly properties, die die klasse kunde im constructor mit den entsprechenden werten belegt.
ich sehe hier offengesagt keinen grund, attributes & reflection zu verwenden.

und im günstigsten fall bist du auch der datenbank-architekt und dann heisst die pk spalte sowieso IMMER "id" und ist IMMER ein uniqueidentifier und dann gibt es natürlich noch ein paar zusätzliche codeeinsparungen...

ist aber nur meine bescheidene meinung.

hth
gruß
ron

26.03.2007 - 17:21 Uhr

hallo

also, falls das jemand mal interessiert:

TableLayoutPanels sind in vererbten Formularen nicht veränderbar.
unabhängig von ihrem Modifizierer.

Ist somit wohl ein Leistungsmerkmal (sprich: feature) von .NET. 😁

gruß
ron

26.03.2007 - 14:02 Uhr

hi folks,

habe ich das (z.B. hier: http://www.developersdex.com/sql/message.asp?p=1119&r=5529401) richtig verstanden, dass der DataAdapter keine default values der datenbank unterstützt, obwohl man mit FillSchema() Angaben zur Tabellenstruktur abgerufen hat?

wer braucht dann noch ein FillSchema()?

eine Datenspalte namens [Created] not null mit getdate() als default wirft in meiner anwendung eine NoNullAllowedException.

wie habt ihr sowas gelöst?

gruß

ron

26.03.2007 - 08:16 Uhr

hi folks,

wir haben uns hier immer mal wieder in ein paar fallen hineinmanövriert, die ich mal als Event Bouncing bezeichnen möchte:

Ein event löst ein event aus, das ein event auslöst, das ein event auslöst....

mit ein bisschen pech ist in der folgekette aller events das ursprüngliche event auch wieder mit drin und dann gibt´s ereignisbehandlungen bis zum sanktnimmerleinstag.... 🙂

wir halten es daher für sehr wichtig, sich vor dem codieren unbedingt gedanken über die ereignisarchitektur seiner klassen gedanken zu machen, denn die delegaten und ereignismöglichkeiten von .net laden zu allerlei tollen dingen ein, die man manchmal besser (sprich: auf direkterem prozeduralen weg) gelöst hätte.

gruß

ron

24.03.2007 - 10:37 Uhr

hallo jürgen,

sorry, aber ich bin ja nicht zum ersten mal hier; die suche hat leider nichts passendes ergeben, sonst hätte ich hier kein thema erstellt...

das problem ist auch nicht, dass protected/public grundsätzlich nicht greift, sondern dass mir das ein problem verschachtelter container-steuerelemente zu sein scheint: das oberste container element (Panel) kann ich wie gesagt prima in der ableitung verändern, nicht aber die elemente des TableLayoutPanels, das aber ebenfalls Protected Internal ist.

24.03.2007 - 09:24 Uhr

hi folks,

ich habe ein Form namens "Desktop";

darin befindet sich ein Panel "DesktopPanel" und im Panel ein TableLayoutPanel "GroupTable". Für alle diese Elemente sind die Modifizierer auf Protected Internal gesetzt.

In einem geerbten Form, das also von "Dektop" erbt, kann ich im Designer nur das DesktopPanel verändern (also z.B. um weitere Controls ergänzen), die GroupTable kann ich nicht ändern.

Wieso? Übersehe ich hier etwas?

Danke für eure Hilfe.

ron

18.03.2007 - 09:37 Uhr

hi hendrik,

da du dir irgendwo merken musst, welche benutzer die löschung akzeptiert haben, brauchst du noch eine tabelle [dbo].[Loeschung] mit bspw. einer spalte [Angenommen] (bit) default = 0 not null

mit einem left join auf

(x.RecordID = loeschung.xID) where (loeschung.angenommen = 0) 

findest du dann alle, die die löschung noch nicht angenommen haben.

gruß
ron

15.03.2007 - 16:09 Uhr

hi svenson,

ja, das stimmt, das geht, aber verlagert das problem nur einen weiteren methodenaufruf höher: Auch in diesem fall muss ja der typ EXPLIZIT bei aufruf der methode angegeben werden.

naja, habe jetzt meinen microkernel um eine überladung von GetInstance erweitert, der nicht generisch ist, wär aber trotzdem eine tolle neue erkenntnis gewesen, wenn sowas ginge 😉

thanx

ron

15.03.2007 - 15:36 Uhr

hi folks,

gibt es eine möglichkeit, das argument einer methode als typ an einen generischen methodenaufruf zu übergeben?

folgendes z.b. geht nicht:


private IBusinessContext SetContext(Type type)
{
   return (IBusinessContext)microKernel.GetInstance<type>();
}

weil type ja nur eine variable ist und nicht den (z.B.) schnittstellentyp nennt, der erwartet wird.

also nochmal in anderen worten: gibt es syntaktisch in C# überhaupt die möglichkeit, die angabe des generic type aus einer variablen zu bilden?

danke

ron

15.03.2007 - 10:17 Uhr

zum Beispiel das ich bei falscher Eingabe eine Meldung kommt, die Komplexer formatiert ist

Dafür gibt es doch dann den ErrorProvider;

die formatierung von ToolTip und ErrorProvider sind in gewissen Grenzen ja auch vornehmbar;

und im "schlimmsten" falle schreibst du deine eigene klasse, die von ToolTip oder ErrorProvider erbt.

15.03.2007 - 10:04 Uhr

hi mipa,

du musst die komplette größe verwenden:


myform.Size = new Size(20, 40);

willst du nur einen wert ändern, bedeutet das entsprechend:


myform.Size = new Size(myForm.Size.Width, 40);

15.03.2007 - 10:01 Uhr

hi marcus,

die angemessene technik wäre eigentlich die klasse ToolTip, zur entwurfszeit in der toolbox verfügbar, gruppe "Allgemeine Steuerelemente"

15.03.2007 - 08:48 Uhr

hi folks,

ich habe folgendes Phänomen mit einer DataGridView.

Um ein Drag & Drop zu ermöglichen, fange ich mit nachstehendem Code das MouseMove-Ereignis ab:


private void DataGrid_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
   if (((e.Button & MouseButtons.Left) == MouseButtons.Left) && (e.Clicks < 2))
      tu_Irgendwas;
}

Das führt aber leider dazu, dass der ERSTE Doppelklick in einer ANDEREN Zeile als die aktuell ausgewählte nicht mehr verarbeitet wird; ein Doppelklick wird jetzt nur verarbeitet, wenn er in der Zeile geschieht, die ohnehin bereits ausgewählt ist.

Das stört natürlich; hat jemand von euch eine Idee?

Ausserdem ist witzigerweise das Argument e.Clicks in obigem code auch bei einem Doppelklick immer 0; wozu gibt es das dann?

danke & gruß

ron

12.03.2007 - 07:57 Uhr

hi fzelle

um geschwindigkeit geht es hierbei eigentlich weniger, sondern vielmehr darum, dass meiner erfahrung nach sql anweisungen aus wartungsgründen in compiliertem code nichts zu suchen haben 😉

gruß
ron

06.03.2007 - 18:06 Uhr

hi sven

du solltest lieber eine user defined function nehmen statt ein argument eine stored procedure als OUT zu "vergewohltätigen":


CREATE FUNCTION meineSumme (
   @Datum   datetime,
   @Name    varchar(10)
)
RETURNS float
AS BEGIN

   declare 
      @result     float

   set @Summe=(Select SUM(Summenfeld) from .... where Name=@Name...

   return @result

END


im code rufst du dann ganz normal das ergebnis ab mit:


   sqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
   sqlCommand.CommandText = "meineSumme";

// Init return object
   object result = DBNull.Value;
   SqlParameter returnVal = new SqlParameter("RETURN_VALUE",SqlDbType.Variant);

// Init return value parameter
   returnVal.Direction = ParameterDirection.ReturnValue;
   sqlCommand.Parameters.Add(returnVal);

// Execute the command
   _Affected = sqlCommand.ExecuteNonQuery();
   result = sqlCommand.Parameters["RETURN_VALUE"].Value;

gruß
ron

06.03.2007 - 09:53 Uhr

hi folks,

wann ist eurer meinung nach eine methode, wann ein property sinnvoller, um von einer klasse nach draussen etwas bereitzustellen?
vorausgesetzt sei mal, es handele sich in beiden fällen um gleich wenig oder viel code.

beispiel: eine klasse soll eine reihe von BindingSource elementen bereitstellen und alle liegen intern im rahmen eines dictionary vor.
ist es eurer meinung nach sinnvoll, das dictionary zu veröffentlichen:


public Dictionary<string, BindingSource> BindingSource 
{
   get { return _BindingSource; }
}

oder besser, eine methode zu implementieren:


public BindingSource GetBindingSource(string tableName)
{
   return this.BindingSource[tableName];
}

danke für eure meinung

ron

06.03.2007 - 08:30 Uhr

in sql umgesetzt:


select 
   min(Zahlenspalte) + 1
from 
   [Tabellenname] t
where not exists (
   select [irgendeineSpalte] 
   from [Tabellenname] t1 
   where t1.Zahlenspalte= t.Zahlenspalte+ 1
)

gruß
ron

05.03.2007 - 18:27 Uhr

ich wusste doch, ich hatte da irgendwann nochmal was cooleres gesehen.

bist der held, herbivore, danke!
(du natürlich auch, peter!) 😉

05.03.2007 - 18:16 Uhr

hi leute,

ich würde gerne zur laufzeit prüfen, ob eine objektvariable einen bestimmten schnittstellentyp implementiert.
im nachfolgenden beispiel soll ein Control bspw. herausfinden, ob das Formular, in dem es sich befindet, die Schnittstelle IDBContainer implementiert.

natürlich kann man über ein try-catch herausfinden, ob das casting geklappt hat:


   private IDBContainer         parentContainer;
   
   try
   {
      parentContainer = (IDBContainer)FindForm();
   }
   catch { /* war wohl nix */ }

die frage ist: geht das auch eleganter?
ist es legitim zum bsp. nachstehendes zu machen:


   if (FindForm().GetType() == typeof(IDBControl))
   {
      // und hier geht´s dann cool zur Sache ...  :-)
   }

danke für eure meinung.

gruß
ron

04.03.2007 - 13:41 Uhr

hi bertl

folgende lösungsansätze:
*bist du bei deinem verbindungsversuch immer noch lokal (auf der gleichen maschine?)
wenn nicht musst du über die oberflächenkonfiguration remoteverbindungen (am besten named pipes und tcp/ip) aktivieren

*installier das (ebenfalls kostenlose) management paket und dann hast du eine verwaltungsoberfläche, in der du das kennwort des sa garantiert ändern kannst. (http://www.microsoft.com/downloads/details.aspx?FamilyID=c243a5ae-4bd1-4e3d-94b8-5a0f62bf7796&DisplayLang=de) *auf welche datenbank versuchst du dich denn zu verbinden? ist die denn schon angehängt? oder bist du sicher, dass du die master ansprichst? *von wo aus kommst du denn? code? hast du mal versucht, mit access, excel oder odbc draufzugehen?

hoffe es waren ein paar neue denkanstöße dabei

gruß

ron

04.03.2007 - 12:35 Uhr

hi heimi,
war ein paar tage offline, daher erst jetzt eine antwort:

also den satz "Ich habe jetzt überall den Typ dateTime genommen" verstehe ich so, dass du jetzt die spalten beibehalten hast, aber alle zum typ datetime gemacht hast.

bei mir ist es so, dass ich sagen wir mal eine tabelle namens [ACTIVITY] habe, die im einfachsten falle lediglich über die spalten
[Typ], tinyInt; (0-Pause, 1-Arbeitszeit, 2-Urlaub, 3-Krankheit, etc.)
[Starts], DateTime;
[Ends], DateTime
verfügen muss sowie über geeignete Fremdschlüsselspalten, um auf eine Person zu verweisen.

Wenn du bei deinem modell bleiben willst, dann solltest du zumindest die formatierung der spalten bei der ausgabe so verändern, dass dort, wo nur das datum interessiert die zeit auch nicht ausgegeben wird, bzw. dort, wo nur die zeit interessiert natürlich das datum unterdrückt wird.

22.02.2007 - 10:26 Uhr

hi junky,

hab deinen vorschlag probiert, aber das property Enabled des UserControls wird nicht verändert, wenn der übergeordnete container enabled ändert; daher ist es so leider nicht machbar.

schade, schien mir ne gute idee zu sein...

22.02.2007 - 09:53 Uhr

ich habe aber noch ein problem.

liegt eine TextBox in einem container, der disabled ist (z.B. Panel) wird zur Laufzeit
die textbox auch schön disabled dargestellt.

ist die textbox in einem usercontrol eingebettet, bleibt sie weiss, als sei sie aktiv.
bis jetzt erzwinge ich die aktualisierte darstellung mit:


protected override void OnPaint(PaintEventArgs e)
{
   Textbox.BackColor = (CanFocus) ? SystemColors.Window : 
                                        SystemColors.ControlLight;
   base.OnPaint(e);
}

das bremst aber ganz gehörig.

hat jemand da noch eine idee?

22.02.2007 - 08:51 Uhr

hi drache,

ist halt ne frage der zuständigkeiten.

in meinem fall ist die textbox an eine datenquelle gebunden, kennt ihre Datenspalte, prüft ob deren AllowDBNull-Eigenschaft wahr ist und leitet daraus einen "Ist Pflichtfeld"-Stern ab.

schon rein objektorientiert betrachtet halte ich es für bedenklich, hier eigenschaften der textbox nach aussen zu stellen, bloss damit der übergeordnete container das zeichnen übernimmt.

dazu kommen herausforderungen an rekursive schleifen, weil die textbox nämlich in einer groupbox des gradientpanels der registerseite x des tabcontrols des panels2 des splitterpanels des armen formulares liegen kann.... 😉

22.02.2007 - 07:42 Uhr

hallo heimi,
wenn es um arbeitszeiten geht: ich habe einen solchen auftrag seinerzeit hauptsächlich über die datenbank gelöst.

[beginn] und [ende] sind hier datetime spalten mit vollständigem zeitstempel.
eine berechnete spalte [Dauer] rechnet für mich die arbeitszeit wie folgt aus:


case 
   when ([typ] = 0) then (datediff(minute,[Beginn],[Ende]) / convert(float,(-60))) 
   when ([typ] = 1) then (datediff(minute,[Beginn],[Ende]) / convert(float,60)) 
   when ([typ] > 1) then 0 
end

mit:
0 - Pause; 1 - Arbeitszeit;

das problem ist u.a., dass jemand ja mehrere pausen machen kann, daher sind alle pausen als negative arbeitszeiteinträge pro tag hinterlegt.
am monatsende lässt du dann bspw. mit einer stored procedure die arbeitszeiten des monats nach mitarbeiter gruppiert summieren.

ein weiteres problem war (und ist ggf. für dich), dass das system einem arbeitstag automatisch eine pause von 30 minuten hinzufügen muss, wenn der mitarbeiter keine gemacht hat aber länger als 6 std. gearbeitet hat (rechtliche vorgabe).

im programm brauchst du also nur die wirklichen beginn- und endezeiten.

wie bernd schon andeutet, hast du dann die timespan als zeitspannen für arbeitszeiten und pausenzeiten.

gruß
ron

22.02.2007 - 00:42 Uhr

hi herbivore,

(bool)(i < Convert.ToInt16(txtLoop.Text)) ist eine merkwürdige Konstruktion stimmt, hatte beim testen auf die schnelle hier einen fehler vermutet, aber lag ja nicht daran... 😉

Besser entweder TextBoxes.Count stimmt !

oder gleich eine foreach-Schleife verwenden. iss net so gut weil dann innerhalb der schleife der index nicht bekannt ist: die textbox weiss ja nichts von ihrer position, oder?

gruß
ron

22.02.2007 - 00:37 Uhr

hey heimi,

warum willst du sie denn unbedingt trennen?

anyway, im günstigsten fall brauchst du die werte der beiden formularfelder nur zu addieren, weil datumswerte intern als gebrochene zahlen codiert sind: ganzzahliger anteil = tag, gebrochener teil = uhrzeit.
dann gibt es ein verabredetes startdatum, bei c# ist die zahl 0 der 1.1.0001, 00:00:00 Uhr

von der sql seite kommend kannst du sie trennen über
convert(varchar, Geburtsdatum, 104)
dabei ist 104 deutsche formatierung mit jahreszahl etc.
guggsdu unter cast/convert der sql doku,

aber wie gesagt, seit datetimepicker und maskedtextbox sehe ich denn sinn nicht so ganz...

gruß
ron

22.02.2007 - 00:18 Uhr

hi folks, wie wäre es mit einer Liste?


public Form1()
{
   InitializeComponent();
   SuspendLayout();
   for (int i = 0; i < 20; i++)
   {
      TextBox tb = new TextBox();
      tb.Size = new Size(100, 20);
      tb.Location = new Point(10, i * (tb.Height +3));
      TextBoxes.Add(tb);
      this.Controls.Add(tb);
   }
   ResumeLayout(true);
}

Mit folgender Schleife kann dann die Sichtbarkeit gesteuert werden:


for (int i = 0; i < 20; i++)
{
   TextBoxes[i].Visible = (bool)(i < Convert.ToInt16(txtLoop.Text));
} 

Ausserdem kannst du nun über die Indizierung eine beliebige Textboxansprechen, ohne ihren "Namen" zu kennen...

und was heisst hier spät... 😉