Hallo,
Zusatzfrage: Geht das auch mit dem LIKE Operator? Wenn ich einen exakten Wert suche bekomme ich das gewünschte Ergebnis aber leider nicht wenn ich mit LIKE arbeite
Danke
gremgiz
Hallo,
vielen herzlichen Dank für die Antwort. Das hat super geklappt. In der Tat kenn TSQL kein MINUS aber EXCEPT
Gruß
gremgiz
Hallo,
danke für die Antwort. Leider ist dies nur die halbe Wahrheit. Die Area kann durchaus noch mehr umfassen. MIt dem Self JOIN komme ich leider nicht weiter. Daher die Frage nach der Rekursion. Es soll also nach beliebigen Kombinationen gesucht werden
Gruß
gremgiz
Hallo zusammen,
verwendetes Datenbanksystem: <MS-SQL 2008>
Eine Tabelle sieht in etwa so aus
1 A Company
1 A SEM
2 B null
3 C Material
4 D SEM
Ich möchte nun alle CustomerID bekommen, die in Area Company UND SEM haben. Das Ergebnis soll also 1 sein. Wie bkeomme ich das mit einer SQL Abfrage hin?
Vielen Dank
gremgiz
Hallo zusammen,
wie das halt so ist. Man sucht tagelang und posted dann - ja und dann findet man die Lösung....
http://www.biggle.de/blog/doppelte-eintraege-aus-einer-datatable-entfernen-linqextension
hat ein sehr gutes Snippet dafür
Hallo zusammen,
Ich habe eine DataTable mit ca. 40 Spalten und ca. 40.000 Zeilen, die an ein DataGridView gekoppelt ist. Über Textfelder kann man in der Liste nahezu nach Belieben filtern, was auch sehr performant funktioniert. Der Benutzer kann Werte filtern oder auch einzelne Spalten ausblenden bzw. wieder einblenden.
Ich möchte nun erreichen, dass wenn eine Benutzer bestimmte Spalten ausblendet nur noch die DISTINCT Werte der DataTable abgezeigt werden. Dazu könnte man DataTable.DefaultView.ToTable(/Distinct/ true, cols[]) nehmen. Wenn relativ wenig gefilterte Daten vorhanden sind (ca. 500 Zeilen) geht auch wunderbar schnell. Werden es mehr dauert es mehrere Sekunden (5-10), bis die DataTable gefiltert ist und der Benutzer weiterarbeiten kann. In der Zeit ist der UI Thread komplett blockiert. Ich suche daher eine schnellere Lösung. Hat jemand eine Idee?
Hallo nochmal,
habe noch ein wenig rumgespeielt und eine Lösung gefunden. Es sieht so aus, als ob sich das Property nicht richtig aktualisiert. In der Datenstruktur setze ich bei einer Änderung des Checkstatus jetzt die andere Variable manuell neu. Damit geht es zumindest.
Danke für die Mühe
Gremgiz
Hallo zusammen,
ich habe ein merkwürdiges verhalten von Radiobuttons, die per Databind gebunden sind. Es handelt sich um zwei Gruppen von Radiobuttons, die jeweils zwei Radiobuttons beinhalten. Komischerweise beeinflussen sich die beiden Gruppen. Wenn ich den jeweils ersten Radiobutton betätige, ändert sich der Wert der zweiten Gruppe.
Um das mal zu veranschaulichen (x = Checked; - = Unchecked)
Initialwert:
1.Gruppe: x -
2.Gruppe: x -
Änderung auf jeweils 2.Radiobutton - ok
Änderung 1. Gruppe auf 1. Radiobutton - ok
Änderung 2. Gruppe auf 1. Radiobutton - Nicht ok
Änderung: 1. Gruppe auf 1. Radiobutton - Nicht ok:
Hat jemand eine Erklärung dafür?
Eine der Gruppen ist in einem Panel abgelegt, die andere nicht. Ich habe auch schon bei Gruppen in Panels (je Gruppe eins) abgelegt - hat aber keinen Einfluss.
Die Bindung sieht wie folgt aus:
Radio1.DataBindings.Add("Checked", Data, "MyRadio1");
Radio2.DataBindings.Add("Checked", Data, "MyRadio2");
Radio3.DataBindings.Add("Checked", Data, "MyRadio3");
Radio4.DataBindings.Add("Checked", Data, "MyRadio4");
Data ist eine Klasse die INotifyPropertyChanged implementiert. Die Implementierung ist ok - sie funktioniert mit allen anderen Daten.
Gruß
Gremgiz
Hallo zusammen,
ich habe ein merkwürdiges Problem bei der Datenbindung.
In einer separaten Klasse werden die Properties definiert. Das ganze sieht in etwa so aus:
public class AddressValue : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
private int addressID;
public int AddressID
{
get
{
return addressID;
}
set
{
addressID = value;
NotifyPropertyChanged("AddressID");
}
}
private string contactForename;
public string ContactForename
{
get
{
return contactForename;
}
set
{
contactForename = value;
NotifyPropertyChanged("ContactForename");
}
}
// und noch einige mehr
Das ganze wird an diverse Steuerelemente in der Hauptform gebunden, was auch wunderbar funktioniert:
//AddressData aus AddressValue initialisieren siehe oben
TB_Forename.DataBindings.Add("Text", AddressData, "ContactForename", false, DataSourceUpdateMode.OnPropertyChanged);
Das ganze wird der Suche übergeben und dort wird eine identische Struktur als Rückgabewert erstellt.
Wenn ich nun folgendes aufrufe:
AddressData = Suchergebnis;
passiert nix. Wenn ich allerdings aufrufe:
AddressData.ContactForename = Suchergebnis.ContactForename;
wird die Datenbindung korrekt dargestellt. Muss ich jetzt wirklich alle Properties manuell zuweisen?
Danke
gremgiz
Hallo,
vielen Dank, das war es. Ziehe jetzt nur noch den Connection String an und baue komplett neue Vebindung.
Hat jemand noch eine Idee bzgl. der 2. Teilfrage: Abfagen von Exceptions wenn nicht Try sondern Using verwendet wird?
Gruß
Gremgiz
Hallo zusammen,
Es wird MS SQL 2008 verwendet.
In einer Applikation werden Daten importiert und mit dem bestehenden Datenbestand abgeglichen. Da diese Aktion viel Zeit in Anspruch nimmt, wurde dies in einen eigenen Thread ausgelagert. Gleichzeitig kann der Anwender ebenfalls mit der zu Grunde liegenden Datenbank arbeiten.
Während der Hintergrundtask läuft bekomme ich beim Datenbankzugriff über fen Worker-Thread immer eine Exception, dass die Verbindung bereits geöffnet ist. Leider verstehe ich nicht warum. Der Hintergrundtask verwendet seine eigene Instanz der Verbindung.
Hier mal die Randbedingungen.
Die SQL Connection ist als statische Variable in einer eigenen Klasse "Constant" deklariert
private const string StrConnect = "verbindung"; //Korrekter String vorhanden
public static SqlConnection SqlConnect = new SqlConnection(StrConnect);
Der Background-Thread wird wie folgt aufgerufen
Thread importThread = new Thread(ImportData);
importThread.Start(Constant.SqlConnect);
Die Methode ImportData sieht grob so aus:
public static void ImportData(Object SqlConn)
{
SqlConnection sqlConnect = SqlConn as SqlConnection;
//...weitere SQL Definition des Kommandos
try
{
sqlConnect.Open();
//...mach was damit
}
catch...
finaly
{
sqlConnect.Close();
}
}
Der Worker Thread holt sich die Verbidung direkt aus der Klasse "Constant". Ich dachte, dass ich mittels der Übergabe der Verbindung an den Background-Thread eine neue Verbindung erstelle, aber offentsichtlich wird die aus dem Verbindungspool genommen. Kann mir jemand sagen was ich falsch mache?
Randfrage: In einigen Diskussionen taucht immer mal wieder auf SQL nicht in Try/catch zu legen sondern Using zu verwenden. Ich habe aber noch nicht herausgefunden, wie dann Exceptions abgefangen werden. Geht das dann überhaupt?
Vielen Dank
Gremgiz
Nach etlichen weiteren Versuchen habe ich eine mögliche Lösung gefunden, die ich Euch nicht vorenthalten möchte.
Tests haben ergeben, dass die Datenbindung durchaus funktioniert, nur zu spät. Sobald die Combobox den Fokus verliert, wird die Datenbindung auch korrekt durchgeführt. Wenn aber noch Events dazwischen hängen, die auf den aktualisierten Wert angewiesen sind, hat man erst mal ein Problem.
Die Lösung erfolgte in zwei Schritten:
Ändern von
Combo1.DataBindings.Add("SelectedValue", MyStruktur, "MyValue");
in
Combo1.DataBindings.Add("SelectedValue", MyStruktur, "MyValue", false, DataSourceUpdateMode.OnPropertyChanged);
Damit wird die Aktualisierung früher erzwungen. Leider noch nicht früh genug für das Event SelectedValueChanged.
Events werden ja in einer definierten Reihenfolge durchlaufen. Ich brauche ein Event, dass erst nach dem Property Change kommt -> SelectedIndexChanged. Wird dieses Event verwendet, erfolgt die Aktualisierung der gebundenen Daten bevor das Event feuert und man hat innerhalb des Events die Daten, die man benötigt.
Ich hoffe das hilft auch anderen...
Gruß
gremgiz
Hallo zusammen,
Eine Combobox will einfach nicht den aktualisierten Wert an eine Variable durchreichen.
Die DataSource der Combobox ist ein Dictionary und wie folgt eingebunden:
Combo1.DisplayMember = "Value";
Combo1.ValueMember = "Key";
Combo1.DataSource = new BindingSource(myDictionary, null);
Das Datenbining sieht wie folgt aus
Combo1.DataBindings.Add("SelectedValue", MyStruktur, "MyValue1");
Der Typ myStruktur is mit INotifyPropertyChanged versehen und funktioniert auch für Textfelder wunderbar. Hier die Implementierung
public class TicketValue : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
private int myValue1;
public int MyValue1
{
get
{
return this.myValue1;
}
set
{
this.myValue1 = value;
NotifyPropertyChanged("MyValue1");
}
}
}
Wenn ich nun in der Form das Event SelectedValueChanged für die Combobox aufrufe, wird der Wert in MyValue nicht aktualisiert. Hat irgendjemand eine Idee, was ich falsch mache?
Erreichen möchte ich, dass der Key an die Variable übergeben wird.
Danke
Gremgiz
Hallo,
das hört sich gut an, werde es mal austesten
Danke
Gremgiz
Hallo,
ich setze in der WHERE Klausel keine Parameter, ich werte sie vielmehr aus. Das ganze ist eine Stored Procedure, auf die von außen zugegriffen wird. Oftmals gibt es den Fall, dass eine tabelle von verschiedenen Quellen aus gelsen werden muss. Meine Idee war es nun für das generelle Lesen von Datensätzen aus der DB eine universelle Stored Procedure zu erstellen, die pauschal in der Lage ist, alle Felder eines Datensatzes zurückzugeben. Welche Datensätze benötigt werden, wird ja über die WHERE Klausel angegeben. Wenn man diese dann noch einschränken könnte (so wie abgebildet), kann man sich das mehrmalige Schreiben der Prozedur sparen.
Ich weiß, dass man solche Abfragen auch über Dynamic SQL machen kann, was mir aber zu aufwendig erscheint bei einfachen Abfragen
Gruß
Gremgiz
Hallo,
geht leider nicht
SELECT Feld1, Feld2, Feld3, Feld4
FROM Tabelle1
WHERE CASE @Ebene
WHEN 0 THEN Feld1 = @Parameter2
WHEN 1 THEN Feld2 = @Parameter2
bringt einen Fehler: Incorrect Syntax near '='
verwendetes Datenbanksystem: MS SQL Server 2008
Hallo,
eine Frage zur TSQL Programmierung. Kann man innerhalb einer WHERE Klausel eine IF Bedingung verwenden, um verschiedene Parameter zu setzen?
Hier mal ein Beispiel
SELECT Feld1, Feld2, Feld3, Feld4
FROM Tabelle1
WHERE
IF @Ebene = 0 THEN Feld1 = @Parameter2
IF @Ebene = 1 THEN Feld2 = @Parameter2
Das würde mir bei vielen Abfrage das Leben doch erheblich erleichtern
Danke
Gremgiz
Hallo,
erst mal Danke dafür. Umweg über CSV wäre machbar. Weg über Excel ist in dem Fall nicht komfortabel. Ich will ja in meiner Applikation bleiben.
Aber nochmal zur ursprünglichen Frage: Gibt es ein Äquivalent zu dem Kommando in TSQL? Kann man es vielleicht über LINQ machen?
Gruß
Gremgiz
Hallo,
MSSQL 2008 wird über Stored Procedures abgefragt. Das Ergebnis soll nach Exel exportiert werden.
In Jet-SQL gab es den wunderbaren Befehl SELECT * INTO [test] IN 'xyz.sls' 'Excel 8.0;' FROM blablub
Der geht leider unter TSQL nicht. Wie löst man das unter TSQL? Gibt es vielleicht eine Möglicht JETSQL Befehle an ein TSQL System abzusetzen (ich denke nein)
Danke
Gremgiz
Hallo,
ich ging bisher davon aus, dass die einzelnen Schichten "in Stein gemeißelt" sind und entsprechend gehandhabt werden müssen. Ich werde es jetzt mal auf diese Art und Weise machen.
Vielen Dank
Gremgiz
Hallo,
Danke für die Anregungen. Ich habe damit einen Ansatz finden können, den ich weiter unten vorstellen werde.
@Herbivore
klingt nach globalen Variablen durch die Hintertür.
Es sind keine globalen Variablen. Es ist vielmehr so, dass eine Programmfunktion mehrfach aufgerufen werden kann (Tabbed Browsing) und unterschiedliche Daten enthält. Somit brauche ich halt für jeden Tab eine eigene Instanz. Würde ich es nicht so machen, würden die Variablen für den Tab A ja auch für den Tab B gültig sein, was falsch wäre.
Bist du dir sicher, dass du das brauchst und dass das ein guter Weg ist?
Zumindest mit meinem Kenntnisstand der Programmierung brauche ich dies - ob das ein guter Weg ist, kann ich nicht sagen. Man kann natürlich die Daten auch im BuinessLayer ablegen, aber da gehören Sie doch nach dem Schichtenmodell nicht hin?
@tom-essen
So ähnlich mache ich es jetzt auch
Hier mal meine Vorgehensweise (von unten nach oben):
DataHold Layer:
Definiert die Variable
namespace datahold
{
public class datahold
{
public int Testzahl { get; set; }
}
}
Data Layer
Definiert eine Klassenvariable für den DataHold Layer. Zwei Methoden kümmern sich um den Schreib- und Lesezugriff
namespace Data
{
public class datalayer
{
datahold.datahold datenhalter { get; set; }
public void writedata(int zahl)
{
switch (datenhalter == null)
{
case true:
datenhalter = new datahold.datahold();
break;
}
datenhalter.Testzahl = zahl;
}
public int readdata()
{
int Zahl = -10;
switch (datenhalter == null)
{
case true:
Zahl = -1;
break;
case false:
Zahl = datenhalter.Testzahl;
break;
}
return Zahl;
}
}
}
Buisness Layer
Ähnlich dem Data-Layer aufgebaut, da in diesem Beispiel nur als Durchreicher fungierend. Klassenvariable für den Data Layer und zwei Methoden für Lesen und Schreiben.
using Data;
namespace Buisness
{
public class buisness
{
datalayer datenlayer { get; set; }
public void buiswrite(int zahl)
{
switch (datenlayer == null)
{
case true:
datenlayer = new datalayer();
break;
}
datenlayer.writedata(zahl);
}
public int buisread()
{
int Zahl = -10;
switch (datenlayer == null)
{
case true:
Zahl = -1;
break;
case false:
Zahl = datenlayer.readdata();
break;
}
return Zahl;
}
}
}
Presentation Layer
Nimmt die Eingabe entgegen und speichert den Wert bzw. Liest den Wert aus und stellt ihn dar.
using System;
using System.Windows.Forms;
using Buisness;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
buisness buislay { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
switch (buislay == null)
{
case true:
buislay = new buisness();
break;
}
int Zahl = Convert.ToInt32(textBox1.Text);
buislay.buiswrite(Zahl);
}
private void button2_Click(object sender, EventArgs e)
{
switch (buislay == null)
{
case true:
buislay = new buisness();
break;
}
label1.Text = buislay.buisread().ToString();
}
}
}
Hallo,
vielen Dank dafür. Es handelt sich aber nicht um Daten, die aus der Datenbank kommen. Das ist genauso gelöst wie beschrieben. Es geht um Laufzeitvariablen, die an verschiedenen Stellen benötigt werden. Diese werden im Presentation oder Buisness erzeugt und sollen dann nach "unten" durchgereicht werden, um an zentraler Stelle abrufbar zu sein. Klar könnte man den bereits beschriebenen Weg für jede Variable einzeln machen, wird aber ziemlich viel. Daher die Frage nach der Instanzierung, so dass ich mit die Klasse als Instanz hole und dann die benötigten Daten auslese bzw. hineinschreibe
Gruß
Gremgiz
Hallo zusammen,
ich bin gerade dabei mich etwas in die Technologie der Schichten einzuarbeiten und stoße dabei auf ein Problem.
Ich habe einen Presentation-, Buisness und DataLayer. Der Datalayer hat noch den DataAccess und den DataHold unter sich.
Der Presentation und Buisness Layer benötigen nun eine Instanz einer Klasse, die im DataHold liegt. Der dem DataHold übergordnete DataLayer kann sich diese ja per "new" holen. Wie kann ich dass nun aber weiter nach oben geben? Der DataLayer hat ja Zugriff auf den DataHold, der Presentation und Buisness Layer hingegen kennen diese Schicht ja nicht und müssen sich das anderwertig holen. Der Presentation aus dem Buisness und der Buisness aus dem DataLayer.
Vielen Dank schon mal
Gremgiz
Hallo nochmal,
ich denke, dass ich das Prinzip eines Interfaces nicht richtig verstanden habe. Daher werden auch meine Probleme mit der Handhabung herühren. Ich möchte daher einmal einen mehr theoretischen Ansatz mit Euch diskutieren.
Nehmen wir einmal an es gibbt ein Programm, das auch vielen Modulen besteht und eine zentrale Instanz, die sagen wir als Verwalter dient. Die einzelnen Module sind komplett autark und beliebig austauschbar. Eines dieser Module möchte nun eine Meldung ausgeben. Darum kümmert isch wiederum ein Modul. Nun hatte ich das so verstanden, dass das Interface eine Art Agent ist, der die Anfrage entgegen nimmt und nachsieht wohin es damit soll. Damit wäre das in der zentralen Logik angesiedelt. Sich einen solchen Agenten selbst zu schreiben ist kein Problem, da es auch nur einen Methodenaufruf darstellt. Dau könnte man sich auch Klassen definieren, um für jede Eventualität gerüstet zu sein. Bisher dachte ich, dass ein Interface genau so ein Agent ist, der mir die Arbeit abnimmt, aber scheinbar ist es nicht so?
Nun etwas praktischer: Das Modul, dass die Meldung ausgeben will, spricht also das Interface an und übergibt die benötigten Parameter (in meinem Fall als Methodenaufruf). Nach den Hinweise in diesem Thread muss ich aber jetzt schon auf den Teil refrenzieren, der das Interface behandelt und genau dass ist es was ich nicht will.
Kann mir jemand ein kleines Beispiel geben wie es funktioniert? Ich stelle mir das so vor, dass Modul A an ein Interface Daten übergibt und vom Interface die Rückgabe erhält. Das Interface und nur dieses soll wissen, was mit den Daten zu tun ist und diese entsprechend verarbeiten - in dem Fall Modul B aufrufen, um die Meldung auszugeben.
Natürlich kann man das ganze ohne Interface machen, ich verspreche mir aber etwas mehr Übersichtlichkeit davon, es mit INterface zu machen.
Danke und viele Grüße
Gremgiz
Hallo,
vielen Dank für die wertvolle Hilfe von Euch.
es gibt weder statische Interfaces noch kann eine statische Klasse ein Interface implementieren. Wurde alles schon ausführlich besprochen.
Ja, das musste ich dann wohl auch einsehen...
Das Design ist ohnehin ungünstig. Du kannst dein Problem lösen, in dem du das Design änderst. Es ist nicht die Aufgabe der Module, Nachrichten auszugeben, sondern das gehört ins GUI.
Genau da liegt der Aufruf schon. Das geht nur aus den Codeschnipseln nicht so hervor. Die Anzeige, dass keine Adressen gefunden sind beherbergt noch eine Option zu einer anderen Suchmethode, die aber nur auf Wunsch angestoßen werden soll. Die eigentliche Ausgabe der Meldung befindet sich im natürlich ebenfalls GUI, jedoch an einer zentralen Stelle. Der hier gepostete Code ist nur ein Teil eines größeren Moduls, dass an den Rumpf angedockt wird. Das Modul selber bildet auch alle benötigten Schichten ab.
Ich bin aber auf einem gutem Wege es hinzubekommen.
Gruß
Gremgiz
Hallo,
ja die strikte Trennung ist gewünscht. Ich skizziere mal kurz wie das ganze, um dass es hier exemplarisch get, aussieht. Es gibt ein Modul Adressen, dass sich um die Suche und Darstellung von Adressen kümmert. Weiterhin gibt es ein Modul Core, das alle Funktionen beinhaltet, die generell benötigt werden. Dazu zählt u.a. die Ausgabe von Programmmeldungen, die typischerweise an verschiedenen Stellen (Modulen) benötigt wird. Das Interface, das beide Welten zusammenbringen soll, liegt momentan in einem weiteren Namespace. Hier kann man sicherlich überlegen, ob die vom Core behandelten Interfaces im gleichen Namespace liegen sollten. Momentan liegen sie in einem eigenen Namespace. Ich habe also jetzt 3 Namespaces:
Erreichen möchte ich, dass die Adressensuche meinetwegen sagen will, dass die Adresse nicht vorhanden ist. Es übergibt also die benötigten Daten für die Ausgabe an das Interface. Das Interface soll nun die Methode aufrufen, die sich um die Ausgabe sämtlicher Programmmeldungen kümmert, das Ergebnis der Meldung entgegennehmen (als Byte Zahl) und dies der eigentlich aufrufenden Methode zurückgeben.
Bisher wurde das übner statische Methoden realisiert, aber im Zuge eines Refactoring soll dies geändert werden, so das austauschbare Module entstehen.
Hier nochmal der aktuelle Code, der nach den Hinweise (danke dafür) entsprechend umgesetzt wurde:
namespace Interfaces
{
public interface IMessages
{
byte ShowMessage(int ID, byte ButtonCount, byte Level, string[] Text);
}
}
using Interfaces;
namespace Addresses
{
public class presAddress_SearchCustomer : IMessages
{
byte IMessages.ShowMessage(int ID, byte ButtonCount, byte Level, string[] Text)
{
IMessages mess = new presAddress_SearchCustomer();
return mess.ShowMessage(ID, ButtonCount, Level, Text);
}
public static void GetCustomer()
{
if (keine Kunden gefunden)
{
ShowMessage(177, 1, 1, null); //Der Aufruf klappt so nicht
}
}
}
}
using Interfaces;
namespace Core
{
public class presCore_Message : IMessages
{
public byte ShowMessage(int ID, byte ButtonCount, byte Level, string[] Text)
{
//Ausgbe und Auswertung
return Rückgabewert;
}
}
}
Gruß
Gremgiz
Das mit "return dein call" verstehe ich jetzt nicht ganz.
byte IMessages.ShowMessage(int ID, byte ButtonCount, byte Level, string[] Text) { return dein call; }
wie kann ich aus der Klasse Suche jetzt direkt darauf zugreifen? Ich babe die Methode nun wie folgt implementiert:
public byte IMessage.ShowMessage(int ID, byte ButtonCount, byte Level string[] Text)
{
//wie aufrufen?
}
Ich kann nicht auf IMessage.ShowCustomer direkt zugreifen und nur ShowCustomer kennt diese Klasse ja nicht, da Sie woanders definiert ist.
Hallo,
ich habe eine Frage zur Nutzung von Interfaces. Ich möchte ein Interface erstellen, um Programmmeldungen auszugeben.
Das Interface:
namespace Interfaces
public interface IMessages
{
byte ShowMessage (int ID, byte ButtonCount, byte Level, string[] Text);
}
Die eigentliche Methode zur Ausgabe
using Interfaces;
namespace Core
public class Message
{
public static byte ShowMessage(int ID, byte ButtonCount, byte Level, string[] Text)
{
//Anzeige, Auswertung und Rückgabe
}
}
Beispielhafte Anwendung des Interfaces
using Interfaces
namespace Addresses
public class Suche : IMessages
{
// Interface Implementierung
public byte ShowMessage(int ID, byte ButtonCount, byte Level, string[] Text)
{
return ShowMessage(ID, ButtonCount, Level, Text
}
//irgendeine Methode
public static void DoSomething()
{
//...commands...
ShowMessage(177,1,1,null);
//...further commands...
}
Dabei kommen zwei Fehler:> Fehlermeldung:
Addresses.Suche implementiert den Schnittstellenmeber Interface.IMessage.ShowMessage nicht. Ist statisch und kann daher keinen Schnittstellenmember implementieren.
Für das für das nicht statische Feld, Eigenschaft oder Methode "Addresses.DoSomething.ShowMessage(int, byte, byte, string[])" ein Objektverweis erforderlich wäre. Wie soll der denn aussehen? Oder habe ich einen generellen Denkfehler drin?
Kann man in statischen Klassen keine Interfaces implementieren?
Hallo,
ich sitze gerade am Refactoring einer Datenbankanwendung. Dazu habe ich eine Frage bzgl. der Windows UserObjects.
Kurz zu den UserObjects: Das sind Daten die jedes Programm anlegt und die für jedes Programm im TaskManager von Windows angezeigt werden können. Bis Windows XP war die Anzahl auf 10000 begrenzt. Ab Windows Vista können die mittels Registry erhöht werden. In meinem Fall bin ich auf die 10000 beschränkt.
Nun zu der eigentlichen Frage: Das Programm nutzt Tabbed Browsing um die Datensätze anzuzeigen. Jeder Tab beinhaltet einen Datensatz. Die Auswahl, welcher Datensatz und wie viele Datensätze angezeigt werden sollen, obliegt dem Benutzer. Beim Öffnen eines neuen Datensatzes in einem Tab wird vor dem Öffnen geprüft, ob die UserObjects überzulaufen drohen. Hintergrund: Wenn die überlaufen knallt es. Da jeder Tab sehr viele Steuerelemente beinhaltet, können ca. 10-20 Tabs geöffnet werden – je nach Inhalt. Gibt es eine Möglichkeit, den Inhalt eines Tabs, der gerade nicht angezeigt wird, irgendwie zu puffern, sprich aus dem Speicher zu entfernen? Wenn der Tab dann aktiviert wird, sollen die Daten wieder geholt werden. Das ganze soll nicht darin enden, dass der Benutzer 5-6 Sekunden warten muss, bevor die Daten wieder da sind, was passieren würde, wenn ich den Tab vollständig entlade.
Ich habe gerade in VS ein wenig rumgespielt, um das Refactoring anzustoßen und hatte dabei ca. 30 Tabs offen, ohne dass es zu nennenswerten Verzögerungen kam. Klar, die Tabs im VS haben kaum Steuerelemente – eigentlich ja nur eines.
Über Hinweise wäre ich dankbar
Ciao
Gremgiz
Aber gerne doch:
namespace XYZ
{
Timer ti = new Timer();
bool doubleclk = false;
class NoSelectTextBox : KryptonTextBox
{
const int WM_LBUTTONDBLCLK = 0x203;
protected override void WndProc(ref Message m)
{
bool fHandled = false;
switch (m.Msg)
{
case WM_LBUTTONDBLCLK:
fHandled = true;
break;
}
if (!fHandled)
{
base.WndProc(ref m);
}
}
}
private void Listenaufruf()
{
for (int i = 0; i < Array.Count; i+=22)
{
KryptonTextBox TextBox = NoSelectedTextBox();
TextBox.MouseClick += new MouseEventHandler(TB_Ticket_MouseClick);
//weitere TB Formatierungen (Font, Name, etc)
//Hinzufügen zum TableLayoutPanel
}
}
private void TextBox_MouseClick(object sender, MouseEventArgs e)
{
ti.Interval = 250;
ti.Tick += new EventHandler(ti_Tick);
if (!doubleclk)
{
doubleclk = true;
ti.Start();
}
else
{
MessageBox.Show("das war ein doppelklick!");
}
}
void ti_Tick(object sender, EventArgs e)
{
ti.Stop();
doubleclk = false;
}
Hinweis: Die KryptonTextBox kommt aus dem Toolkit von Component Factory und basiert auf der WinForms TextBox. Alle Properties sind vererbt
Habe es gerade probiert - funzt leider nicht. Gleiche wie vorher. Rand geklickt - geht. Innerhable der TB Doppelklick geht nicht. Code habe per Copy& paste zu testzwecken genommen. Die Variablendeklaration für das event sind im Kopf der Klasse definiert, in der das Event aufgerufen wird.
Ich glaube ich bleibe bei dem Button 😦
Gruß
Gremgiz
Ich werde es mal testen. Vielen Dank Euch allen
Gruß
gremgiz
Vielen Dank dafür-. Das hat genau mein problem gelöst. Warum ich das trotz stundenlanger suche nicht gefunden habe bleibt wohl ein geheimnis
😃
Gruß
Gremgiz
@Mr. Sparkle: Jedes programmerzeugt die völlig autark. Da kann man nicht eingreifen. Wenn du z.B. eine Textbox erstellst hast du mind. 1 UserObject erzeugt. Das handelt Windows automatisch. Warum die limitiert sind - Gute Frage für Redmond - vermutlich performance und Stabilität.
Wie schon erwähnt, man kann sich die Anzahl im Taskmanager unter Prozesse ansehen, wenn man sich die Spalte reinholt (Ansicht - Spalten wählen)
gruß
Gremgiz
Das vorgeschlagene habe ich schon probiert. Das gibt mir aber nicht die UserObjects sondern alles mögliche
Benutzer Objecte (engl. User Objects) werden vom Programm erzeugt. Pro Anwendung sind diese auff 10000 limitiert. Da meine Anwendung sehr viele user objects erzeugt will ich einfach sicherstellen, dass die Grenze nicht erreicht wird. Diese kann man sich im Taskmanager unter Prozesse anzeigen lassen (muss manuell hinzugefügt werden - genauso wie die Anzahl der GDI Objects)
Hallo,
um ein wenig Sicherheit in mein Programm zu bringen, möchte ich periodisch die Anzahl der Benutzer Objecte abfragen, wie man sie auch im Taskmanager sieht. Wie kann das bewerktsetlligt werden? Über Process.GetCurrentProcess bekomme ich die Info nicht
Gruß
Gremgiz
Nun ja, Select hilft nicht, wie bereits beschrieben. Momentan habe ich mir noch nen Button dazugebaut. Ist zwar nicht ganz so komfortable aber es hilft erst mal.
Danke
PS: Wenn Ideen bestehen - her damit 😃
Hallo,
ich erzeuge zur Laufzeit einige Textboxen, die ich mit einem Doppelklick Event versehe. Wenn ich in der Textbox einen Doppelklick mache, wird jedoch nur das Wort markiert udn das Event nicht ausgeführt. Klicke ich auf den Rahme der Textbox feuert das Event. Ich will aber nicht den text markieren, sondern das Event ausklösen. Kann mir bitte jemand helfen, wie ich das lösen kann?
Danke
gremgiz
Hallo,
so meine Tischkante hat eine Bissspur mehr... Typischer Fall von Eigendau. Die Zeile war nicht hoch genug, um den text anzuzeigen 😦
Danke
Gremgiz
Hallo,
vielen Dank dafür. Es hilft mir nur leider nicht weiter. Hat jemand vielleicht 2-3 Zeiolen Beispielcode?
Danke
gremgiz
Hallo,
ich habe ein DataGridView, dass unter anderem eine Button-Spalte hat. Per Programmcode werden die Zeilen befüllt. In Abhängigkeit einer Bedingung soll der Button mit Yes oder No beschriftet werden. Nur bekomme ich das nicht hin. Die Beschriftung wird nicht übernommen.
Hier mal mein Code:
NewRow.Cells[5].Value = "No";
Tabelle.Rows.Add(NewRow);
Alle anderen Werte wie z.B. Text oder Datumswerte werden übernommen. WIe kann ich den Button programmtechnisch beschriften?
Gruß
Gremgiz
Jetzt wirds lustig. Habe noch mal den Originalcode mit FieldSetText genommen. Sobald ich das Feld verlasse, erschitn der Text da wo er soll. Ich kann das Feld zwar nicht editieren, aber der Text scheint nur nicht sichtbar zu sein
Entweder ist heute nicht mein Tag oder ich bin wirklich nicht clever genug...
Das spukt mir gerade ne TargetInvocationExcpetion raus ("Member not found").
Hier mal die relevanten Zeilen:
Object uidoc = NotesUIWorkspace.InvokeMember("ComposeDocument", BindingFlags.InvokeMethod, null, ws, new Object[] { mailServer, mailFile, "Memo", 0, 0, true });
Type NotesUIDocument = uidoc.GetType();
Object doc = NotesUIDocument.InvokeMember("Document", BindingFlags.GetProperty, null, uidoc, new Object[] { mailServer}); //Hier kommt die Exception
Type NotesDoc = doc.GetType();
NotesDoc.InvokeMember("ReplaceItemValue", BindingFlags.InvokeMethod, null, doc, new Object[] { "sendto", "Her damit" });
Vielen Dank dafür. Habe schon einwenig gespeilt und bin wieder auf die Nase gefallen. Das Feld "SendTo" scheint mir nicht im UI vorhanden zu sein. Jedenfalls läuft FieldSetText nicht. Ich habe mal im Originalen Code geschaut und da nehmen die REPLACEWITHITEM, was aber nicht im UI ist. Wie kann ich jetzt das Feld setzen?
Die Fragen sind ganze einfach: Wie kann ich eine E-Mail so erzeugen, dass ich sie bearbeiten kann (Übergabe aus C#)?
Mittlerweile geht zumindest das Frontend auf und ich kann teile beschreiben. Das ist ne Datenbank, die mal irgendwer gestrickt hat, der nicht mehr im Zugriff ist.
Eine Zeile meines Codes:
NotesUIDocument.InvokeMember("FieldSetText", BindingFlags.InvokeMethod, null, uidoc, new Object[] { "EnterSendTo", sendto });
Mein Frage geht auf den Teil: ("FieldSetText": Wo gibt es eine Übersicht aller "Befehle"/Member?
gruß
gremgiz
Ja genau die ist es. Die läuft äußerst instabil. Ich denke das kommt daher, dass ich VBA 1:1 nach VB portiert habe (kann weder das eine noch das andere richtig). Irgendwie knallt es immer wieder. Die Fehler sind immer anders. Daher will ich die wegwerfen und neu machen
Ja den kenne ich. Dabei geht es aber um das automatisierte Senden einer E-Mail ohne dass man das Notes Frontend benötigt. Und genau das brauche ich
Hallo,
ich bin gerade dabei über eine Anwendung eine E-Mail in Lotus Notes zu generieren und bekomme es nicht hin. Verwendet wird Lotus Notes 7.0. Kann mir dabei bitte jemand helfen? Ich weiß nicht auf wie vielen Seiten ich im Netzt schon war, aber so richtig gefunden habe ich nichts.
Was soll im einzelnen gemacht werden:
Über das C# Programm soll ein Template an Lotus übergeben werden. Dieses soll dann in Lotus Notes weiter bearbeitet werden können und gesendet werden.
Ich denke, dass hier die Background und die Frontendklassen benötigt werden.
Es gibt eine funktionierende Lösung in VBA, die ich nach besten Wissen in eine VB.DLL überführt habe. Jedoch läuft die nicht stabil und es kommt immer zu Abstürzen. Daher will ich das ganze noch einmal sauber aufsetzen.
Hat jemand Erfahrung, wie man C# an Lotus koppelt und wenn ja wie geht das im Detail?
Danke
gremgiz