Laden...

Forenbeiträge von Cannon Ingesamt 282 Beiträge

03.03.2017 - 07:56 Uhr

Ich greife das Thema mal wieder auf, auch wenn es schon sehr alt ist. Dennoch istd as aktuell, weil auch ich nicht mit der automatische Skalierung zufrieden sind. Weiß denn jemand, wie die Icons in der Resource so eingepackt werden, dass Windows auch automatisch die Richtige Größe nimmt? Ich finde dazu nichts so richtig. Das soll mindestens ab Windows 7 funktionieren.

28.02.2017 - 22:02 Uhr

Das Icon der Anwendung 16-256 Pixel
Das Icon einer Form 16-32 Pixel

So habe ich das jetzt auch gemacht und ich bin damit zufrieden.

Grundsätzlich stimmt aber wohl, was die anderen sagen, dass man das Icon einfach in mehreren Größen einpacken soll. Fraglich ist allerdings, ob Windows dann auch das Richtige auswählt. Ich vermute mal, dass in Windows Forms zumindest, die Standardgrößen, wie oben angegeben fest verankert sind und die Rechtlinien für Resourcen für Kacheln und Symbole nicht wirklich funktionieren. Zumindest wohl nicht unter Windows 7.

28.02.2017 - 07:16 Uhr

Anscheinend ist das wirklich ein Bug von Windows 7. Bei meiner Recherche im Internet bin ich darauf gestoßen. Ich habe das Problem jetzt so gelöst, dass ich die 256er Icons aus dem Hauptfenster entfernt und durch 32er Icons ersetzt habe. Damit past das im Audio-Mixer von Windows 7, der die Icons leider nicht skaliert. Das Programmsymbol hat dennoch eine 256er Auflösung, damit man auch große Symbole anzeigen kann.

27.02.2017 - 09:15 Uhr

Ich glaube damit geht das nicht. Da kann ich ja nur die Lautstärke der Sprachausgabe ermitteln.

Ich habe das jetzt mit NAudio gelöst. Damit kann ich den PeakLevel messen und da taste ich dann eine Sekunde (im 1/10-Sekunden-Takt) ab. Dann habe ich schon entsprechende Werte.

Allerdings ist mir aufgefallen, dass unter Windows 7 im Audio-Mixer das Icon meiner App nicht herunterskaliert wird, deshalb ist die ganze Oberfläche das Lautstärke-Mixers kaputt. Anscheinend ist das ein Fehler in Windows 7. Wie kann ich den denn umgehen, ohne mein Icon zu reduzieren? Ich nutze dafür 256x256 Punkte.

25.02.2017 - 20:59 Uhr

Hallo,

ich suche nach einer Möglichkeit unter Windows die globale Ausgabe-Lautstärke zu ermitteln. Hintergrund ist, dass ich einen Ton ausgeben will, der von der Lautstärke her abhängig von der aktuellen Ausgabe in Windows ist.

Das heißt ich suche KEINE Möglichkeit zu ermitteln, wie die Master-Lautstärke eingestellt ist, sondern ich will den Lautstärke-Level über einen kurzen Zeitraum messen. Ich bin mir nicht sicher, ob ich den Peak-Level auslesen will oder eher etwas anderes, weil ich die subjektiv empfundene Lautsärke ermitteln will.

Gibt es da Ansätze? Ist mit NAudio eine Lösung möglich?

07.08.2013 - 21:56 Uhr

Naja SendKeys kann doch ganze Strings versenden und mit WaitSendKeys wartet der doch auch noch auf die Rückmeldung ..... wofür wäre dann der Sleep noch notwendig? Kann man den mit SendKeys einfach ein Tab einfügen?

06.08.2013 - 19:33 Uhr

Ich möchte mittels eigenem Hotkey die Zwischenablage als Tastendruck einfügen. Hintergrund ist der, dass ich ein Webformular habe, was ich mit Zahlen füllen muss. Diese Zahlen habe ich bereits mit Tabulator-Taste getrennt (aus Excel VBA) in die Zwischenablage kopiert. Tabulator, deshalb, um ins nächste Feld zu gelangen.

Allerdings habe ich 2 Methoden probiert, die beide nicht funktionieren:

  1. SendInput: Was muss ich bei den TAB-Tasten beachten? Den String aus der Zwischenablage einfach an SendInput zu schicken geht jedenfalls nicht. Im Texteditor geht es. In Excel klappt das schon nicht (alle Werte werden OHNE Tab in eine Zelle gepackt).

  2. SendKeys: Klappt auch nicht, da bei dem 2. Aufruf von SendKeys die Funktion einfach nichts ausgibt.

Welche wäre denn eigentlich die Richtige Lösung, um die komplette Zwischenablage, so wie sie ist als Tastendrücke in einem aktiven Fenster/Formular/Anwendung zu simulieren?

19.07.2013 - 11:08 Uhr

Danke.. ich habe anscheinend den Wald vor lauter Bäumen nicht gesehen. BaseUser war null ...

@Abt:
Mir ist nicht ganz klar, was Du mir mitteilen möchtest.

  1. Ich nutzte EF 5.0 und Net 4.5. Wieso soll ich downgraden?
  2. Ist nur ein byte, kein Enum.

Prüft man lieber mit Any() oder mit Count() ?? Gibt es da Performance-Unterschiede?

19.07.2013 - 10:12 Uhr

verwendetes Datenbanksystem: EF 5.0

Ich schaffe es nicht herauszufinden, ob Daten vorhanden sind oder nicht. Meine Abfrage sieht folegndermaßen aus:


_dbSet = context.Set<User>();
var set = _dbSet.Where(e => (e.BaseUser.UserId == user.BaseUser.UserId || e.UserId == user.BaseUser.UserId) && e.AccessLevel <= user.AccessLevel);

Allerdings kann es durchaus passieren, dass Where keine Werte zurückgibt. Aber wie kann ich das prüfen? Ich bekomme immer nur eine Exception "Die statische Methode erfordert ein Ziel".

if (set == null) funktioniert ja nicht. .. achja LazyLoading ist aktiviert.

27.06.2013 - 09:31 Uhr

@Abt: In diese Fall geht es ja nicht darum Änderungen zu verfolgen, sondern um darüber zu reden, warum die UnitOfWork oder auch der DbContext nur eine "kurze" Lebensdauer haben sollte.

Ich sehe halt einfach die Gefahr, dass ich die Daten ständig vom Server lade, obwohl das unnötig wäre. Auf der anderen Seite sehe ich die Aktualisierung der Datensätze nicht, wenn ich die UnitOfWork auf Dauer behalte und irgendwann ist auch die gesamte Datenbank im Speicher gecacht. 😉

27.06.2013 - 08:20 Uhr

Ich arbeite bereits mit UnitOfWork und Repositories.

Auch, wenn ich die Artikel lese, hilft es mir nicht weiter, da sich mir nicht genau der Grund erschließt. Im Falle von WPF geht es darum die UnitOfWork pro ViewModel zu "erneuern". Aber warum? Ist SqlChangeNotifier nicht die bessere Alternative?

27.06.2013 - 08:18 Uhr

Danke .. umgesetzt .. funktioniert!

26.06.2013 - 19:13 Uhr

zu 1.: MAn könnte ja auch durchaus dass Passwort für den Datenbankzugriff in einem Dialog übergeben und nicht speichern. Die Sicherheit wäre am höchsten, da nur die, die das PAsswort können auf die Db zugreifen können.

zu 2.: Wenn Du das in C# schreibst kannst Du doch einen "Passwort ändern" (Dialog) schreiben. Das Passwort sollte aber verschlüsselt in der Datenbank gespeichert werden, z.B. md5.

zu 3.: Entweder kommt jeder Benutzer seine individuellen Zugriffsrechte mittels eines Levels oder separate, die man ja auch in der Db speichern kann. Bestimmte Bereiche im Programm werden dann abhängig vom Level oder von den Rechten ausgeblendet.

26.06.2013 - 12:36 Uhr

Nach einigen Experimenten mit dem Context unter dem Entity Framework (mit SQL-Server) konnte ich feststellen, dass Änderungen der Datenbank erst dann bemerkt werden, wenn der Context verworfen und neu erzeugt wird. Das heißt das ETF cacht sozusagen alle geladenen Datensätze (LazyLoading ist aktiviert). Jetzt gab es verschiedene Ideen:

  1. Der Context bleibt solange am Leben, wie quasi die Datenbank benötigt wird - im Zweifelsfall solange, wie die Anwendung läuft. Vorteil: Ein Datenzugriff passiert nur dann, wenn Änderungen erfolgen und NICHT bei jedem Anzeigen der Daten. Nachteil: Ich bemerke andere (externe) Änderungen der Daten nicht - könnte das aber z.B. mit einem ChangeNotifier abfangen.

  2. Der Context wird für den einmaligen Datenzugriff erzeugt und dann wieder verworfen, bleibt also in meinem Beispiel unter WPF nur für das aktuelle ViewModel aktiv, danach wird er wieder verworfen. Vorteil: Die Daten sind meist aktuell. Nachteil: Ich muss bei jedem Öfnen eines ViewModels alle Daten von der Datenbank erneut laden. Wenn das ViewModel lange offen steht, kann es sein, dass Daten dennoch nicht mehr aktuell sind.

Welche Methode ist die bessere unter der Maßgabe, dass die Anbindung zur Datenbank auch übers Internet oder VPN laufen kann? Oder gibt es ganz andere Gedankenansätze?

26.06.2013 - 12:28 Uhr

Code First wird ja immer populärer. Deshalb möchte ich auch diese variante nutzen. Allerdings stehe ich vor ein paar Herausforderungen, die einen das Leben nicht unbedingt leichter machen.

  1. Ich mag den EDMX-Designer nicht, denn es ist leichter die Datenbank direkt zu erstellen, als über den Designer das Model und daraus die DB zu generieren. Gibt es eine Möglichkeit auch ohne EDMX-Designer die Datenbank aus dem Model (per Hand in C#) zu generieren?

  2. Ich nutze GUIDs (NEWSEQUENTIALID) um mir die Möglichkeit einer eventuellen späteren Replikation der Datenbank zu ermöglichen. Nun ist es aber so, dass der Designer das nicht in dem Db-Skript umsetzen kann, weil er das auch nicht weiß (StoreGeneratedPattern ist gesetzt). Wie kann man das für alle Tabellen automatisieren, um nicht per Hand jedes mal das DB-Skript nachzuarbeiten?

23.06.2013 - 20:40 Uhr

Ich nutze die Regionen konsequent. Dann weiß ich genau, wo ich was finde. Events bekommen eine seperate Region. Ich trenne zwischen privaten, öffentlichen und vererbten Methoden (override) und separiere die entsprechend.

23.06.2013 - 14:27 Uhr

Danke. Beide Lösungen funktionieren auf ihrer eigenen Art.

Lösung von herbicore:
Ich habe darüber bereits in diesem Forum gelesen, war aber der Meinung, da ich das mit dem Event anstoße sollte es kein Problem sein. Deine Lösung funktioniert, wenn ich Invoke über das Codebehind der View ausführe. Allerdings nicht, wenn ich mich nicht im Control befinde. Das heißt für externe Shutdown oder Close-Klassen scheidet das aus. Oder kann man irgendwo den Hauptthread ermitteln und mit übergeben?

Lösung von Khalid:
Einfach umzusetzen, da ich die gesamte Methode abkapseln kann und nirgends weiter auf andere Threads achten muss.

Ich habe eine interessanet Möglichkeit gefunden mit Multithreading unter WPF zu arbeiten. Mit AsyncDelegateCommand. Das ist super und einfach. Allerdings gibt es wieder das Problem, wenn ich irgendwie zurück zur UI will brauche ich den Haupthread. Kann man den irgendwo ermitteln und übergeben? Und wie kann ich Invoke ausführen, wenn ich mich NICHT im UI befinde? Zum Beispiel in meiner Shutdown-Klasse:

Application.Current.Shutdown();

21.06.2013 - 11:05 Uhr

Ich greife hier auf eine Datenbank zu. Damit mir das UI nicht blockiert und ich nebenbei auch noch was anzeigen kann starte ich den Datenbankzugriff asynchron.

Das Ganze funktioniert wunderbar. Allerdings wird das ContinueWith wohl in einem anderen Therad gestartet. Eigentlich sollte es aber im Hauptthread starten, wenn der andere Thread aus ValidDbAsync fertig ist. Denn spätestens beim Zugriff auf Close(), was dazu führt das an späterer Stelle das Fenster geschlossen wird, wird eine Exception ausgelöst. Die Frage ist also, wie kann ich das vermeiden?

		void TryLogin()
		{
			if (String.IsNullOrEmpty(LoginUsername)) {
				LoginErrorInfo = "Bitte einen Benutzernamen eingeben!";
				StartLogin();
			} else {
				LoginShown = false;
				IsBusy = true;
				// init unitofwork and check database
				InitUnitOfWork(DatabasePassword);
				// validate datebase and connection
				WorkUnit.ValidDbAsync().ContinueWith((t) => {
					IsBusy = false;
					if (t.Result == UnitOfWork.DbResult.DatabaseNotFound) {
						ShowDialog("Die Verbindung zu Datenbank konnte nicht hergestellt werden. Bitte prüfen Sie Ihre Internetverbindung oder probieren Sie es zu einem späteren Zeitpunkt erneut.",
							"Fehler", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, ShutdownCallBack);
					} else if (t.Result == UnitOfWork.DbResult.IncorrectSchema) {
						ShowDialog("Die Programmversion ist veraltet. Aktualisieren Sie das Programm, um fortzufahren!",
							"Fehler", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, ShutdownCallBack);
					} else if (t.Result == UnitOfWork.DbResult.UnknownOpenError) {
						ShowDialog("Unbekannter Fehler beim öffnen der Datenbank. Probieren SIe es zu einem späteren Zeitpunkt erneut!",
							"Fehler", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, ShutdownCallBack);
					} else if (t.Result == UnitOfWork.DbResult.UserOrPasswordFailed) {
						LoginErrorInfo = "Der Sicherheitschlüssel ist nicht korrekt.";
						StartLogin();
					} else {
						// validate checkin
						User user = WorkUnit.Users.QueryFirst(u => u.UserName == LoginUsername);
						if (user != null) {
							if (String.Compare(user.Password, LoginPassword) == 0) {
								WorkUnit.LoginUser = user;
								Close();
							} else {
								LoginErrorInfo = "Das eingegebene Passwort ist falsch!";
								StartLogin();
							}
						} else {
							LoginErrorInfo = "Der Benutzername existiert nicht!";
							StartLogin();
						}
					}
				}, TaskContinuationOptions.OnlyOnRanToCompletion);
			}
		}

		public async Task<DbResult> ValidDbAsync()
		{
			DbResult result = DbResult.Ok;
			try {
				SqlConnection con = new SqlConnection(_context.Database.Connection.ConnectionString);
				await con.OpenAsync();
				con.Close();
			} catch (SqlException ex) {
				switch (ex.Number) {
					case 11001:
					result = DbResult.DatabaseNotFound;
					break;

					case 18456:
					result = DbResult.UserOrPasswordFailed;
					break;

					default:
					result = DbResult.UnknownOpenError;
					break;
				}
			}
			if (result == DbResult.Ok) {
				var versions = Versions.FirstOrDefault();
				if (versions != null) {
					if ((_majordbversion != versions.MajorVersion) || (_minordbversion != versions.MinorVersion)) result = DbResult.IncorrectSchema;
				}
			}
			return result;
		}
23.05.2013 - 23:41 Uhr

Also wieder was neues gelernt. Das Beispiel mit dem Event funktioniert soweit, alllerdings befindet sich dann zu viel Model Code im ViewModel. Außerdem ist natürlich die Frage, wie bekomme ich die PasswordBox dann nach mit IDataErrorInfo zum funktionieren. Das setzt ja ein Binding vorraus. Zumindest in meinem Beispiel.

Ich möchte ja angezeigt bekommen, wenn die Passwörter nicht übereinstimmen.

23.05.2013 - 00:57 Uhr

Ich versuche schon seit geraumer Zeit eine einfache Lösung für das Problem zu finden. Wie zum Teufel bekomme ich das Passwort in mein ViewModel. Das Passwort sollte nicht unverschlüsselt im Speicher liegen, demnach macht es keinen Sinn Dependency-properties zu nutzen, um das PW zu binden. Weiterhin ist es nicht möglich von meiner View (Codebehind) aufs Viewmodel zuzugreifen, um das verschlüsselte Passort (MD5) ans ViewModel zu übertragen. Wie kann man das Problem elegant lösen?

23.05.2013 - 00:13 Uhr

Die Queries gehen ja auch problemlos. Aber eben nur mit den bereits beschriebenden Einschränkungen.

Gibt es denn eine gute Alternative zum EF? Es gibt ja doch immer wieder neue Haken, z.B.: CodeFirst oder DbFirst -> Handarbeit ist immer angesagt, wenn man die Db aus dem Model generieren will oder das Model aus der Db, weil entweder StoreGeneratedPattern im Model nachträglich gesetzt werden muss oder in dem Db-Skript der Default-Wert für den Primärschlüssel gesetzt werden muss, wenn man mit GuiIds arbeitet.

23.05.2013 - 00:07 Uhr

Deien Hinweise haben mir geholfen, dass Problem zu lösen. Ich speichere jetzt alle "Fehlerstrings".. (ich muss die mal so nennen) in einem Dictionary und rufe PropertyChanged auf, wenn sich Änderungen ergeben. Die IDataErrorInfo-Schnittstelle bediene ich dann aus dem Dictionary. Das Ganze nutze ich jetzt als Basisklasse für meine Models.

14.05.2013 - 22:00 Uhr

Das klingt alles logisch. Aber irgendwann muss ich ToList() aufrufen, sonst erhalte ich Fehlermeldungen, dass irgendwelche DataReader noch geöffnet sind - vermutlich weil der Lesevorgang noch nicht abgeschlossen ist.

Grundsätzlich geht es ja auch nicht darum mehrere Queries verschachtelt aufzurufen, sondern die komplexen überhaupt nutzen zu können.

Die FK-Spalte kann ich nicht zufügen, da im Model die "tabelle" ja garnicht mehr direkt vorhanden ist - es handelt sich hier wie gesagt nur um eine reine Join table, die keien FK enthalten darf. Gibt es den zu dem Thema noch weitere Quellen, wo ich mal lesen könnte?

Mir erschließt sich nur der Sinn nicht ganz. Wenn das EF so "bequem" entwickelt wurde, dass man eben diese Join-Tables ausblendet, wenn man Tabellen mit n:m - Beziehungen anspricht, dann stelle ich mir die Frage, wie man die überhaupt jemals filtern können soll, ohne alle Daten zu laden und die auf diem Client einzeln durch zu iterieren.

14.05.2013 - 12:13 Uhr

Ja und genau da ist die Frage, wie stoße ich die Validierung der anderen Werte idealerweise an. Ich brauche ja ein PropertyChanged-Event, um die Validierung des Wertes durchzuführen und ggf. einen Fehlerstring zurückzugeben, der dann im View angezeigt wird. Oder sehe ich das falsch?

13.05.2013 - 10:09 Uhr

Es geht aber nicht immer eine Id zu übergeben. Nämlich genau dann, wenn keine Id existiert, die ich abfragen könnte, da die Tabelle EmployeeOffice nur eine Join-Tabele ohne Ids ist und die in EF auch ausgeblendet wird.


var employees = WorkUnit.Employees.GetAll();
foreach (Employee employee in employees) {
	if (employee.Offices.Contains(CurrentOffice)) Employees.Add(employee);
}

In diesem Beispiel, muss ich alle Employees aus der Datenbank laden, nur um ein paar zu wählen, die diesem bestimmten Office zugeordnet sind. Sinnvoll wäre es die doch irgendwie in eine Query zu packen. Allerdings ist natürlich die Frage, ob das überhaupt in SQL so umsetzbar wäre, ohne alle Datensätze erst einmal zu laden.

Sinnvoll wäre doch:


var employees = WorkUnit.Employees.Query(e => e.Offices == CurrentOffice);

oder:


var employees = WorkUnit.Employees.Query(e => e.Offices.Contains(CurrentOffice));

Aber selbst, wenn ich die zerlege fällt mir keine Möglichkeit ein zu verhindern alle Datensätze zu laden.

13.05.2013 - 09:56 Uhr

DU könntest es andersherum machen. Das Model nicht aus der Datenbank generieren, sondern die Datenbank aus dem Model generieren. Wenn ich es richtig verstanden habe, wolltest du ja ohnehin die Datenbank aus dem Code updaten.

Grundsätzlich sehe ich selten einen Sinn vom EF irgendwas zu SQL zu extrahieren. Dann macht es doch mehr Sinn gleich mit SqlConnection und SqlCommand zu arbeiten.

12.05.2013 - 22:54 Uhr

Ich nutzte die IDataErrorInfo-Schnittstelle um meine Steuerelemente zu validieren. Nun möchte ich aber gleichzeitig mehrere Steuerelemente validieren, wenn die irgendwas mit einander zu tun haben. Einfaches Beispiel:

3 Textboxen: Die Zahlen 1, 1 und 2 sind deren Inhalt. Die Fehlerüberprüfung soll nun feststellen, wenn das Ergebnis nicht mehr oder es stimmt. Das heißt jetzt ist alles okay, sobald ich aber in dem Beispiel eine Textbox ändere sollen alle 3 einen Fehler melden.

| 1 | + | 1 | = | 2 |

Der UpdateSourceTrigger ruft ja die Validierung auf, wenn PropertyChanged eintritt, aber eben nur für die eine TextBox und nicht auch für die anderen. Ich könnte natürlich das PropertyChanged für die andren TextBoxen wären der Validierung aufrufen, aber dann befinde ich mich ja in einer Endlosschleife.

Habt ihr da einen Tipp?

11.05.2013 - 22:09 Uhr

Das EF macht einen vieles leichter. Die Abfragen sind einfach und bringen schnell Ergebnisse. Aber wenn ich komplexe Abfragen machen möchte, dann geht das nicht. Beispiel:

_dbSet ist ein IDbSet<T>


public IEnumerable<T> Query(Expression<Func<T, bool>> filter)
{
	return _dbSet.Where(filter).ToList();
}

funktioniert:


var phones = WorkUnit.Phones.Query(e => e.UserId == CurrentUser.UserId);

funktioniert nicht, da nur primitive Typen unterschützt werden:


var phones = WorkUnit.Phones.Query(e => e.User == CurrentUser);

Das ist nur ein vereinfachtes Beispiel, da es mir nur um den Sinn an sich geht. Das Ziel soll ja auch sein sich von den Ids zu lösen und es gibt ja auch nicht immer ein Id-Spalte. Nämlich dann, wenn es um reine Jointabelle (Pure Join Table, PJT) handelt.

Habt ihr da eine Idee zu?

05.05.2013 - 09:08 Uhr

Ich habe das inzwischen auch so ähnlich wie witte gemacht. Nur, dass ich die Zurodnung direkt in der Personal-Klasse mache und die manuell setzen kann. Sonst wird es wegen der Repositories un dem UnitOfWork etwas umständlich.


		void Load()
		{
			// load users
			Users.Clear();
			var users = WorkUnit.Users.Query(e => e.AccessLevel <= AccessLevelProperties.Level);
			foreach (User user in users) {
				Users.Add(user);
			}
			UserCollection.MoveCurrentToFirst();
			// load clubs
			Clubs.Clear();
			var clubs = WorkUnit.Clubs.GetAll();
			foreach (Club club in clubs) Clubs.Add(club);
			ClubCollection.MoveCurrentToFirst();
		}

		void LoadAssigns()
		{
			foreach (Club club in Clubs) {
				club.IsUserAssigned = (club.Users.Contains(CurrentUser)) ? true : false;
			}
			_assignsloaded = true;
		}

		void SaveAssigns()
		{
			if (!_assignsloaded) return;
			foreach (Club club in Clubs) {
				if ((club.IsUserAssigned) && (!club.Users.Contains(CurrentUser))) {
					club.Users.Add(CurrentUser);
				} else if ((!club.IsUserAssigned) && (club.Users.Contains(CurrentUser))) {
					club.Users.Remove(CurrentUser);
				}
			}
		}

LoadAssigns() und SaveAssigns() wird über CurrentChanging und CurrentChanged-Ereignisse der UserCollection gesteuert.

30.04.2013 - 00:23 Uhr

Die Frage ist dann evtl. wie die Zahlen umgewandelt wurden?

28.04.2013 - 11:18 Uhr

Ich habe es hier ins Thema gestellt, weil es weniger um Daten, als um das anbinden der Daten geht. Quelle der Daten ist das Entity Framework.

Es geht um folgendes: Ich habe eine Klasse "User" und eine Klasse "Shops" die beiden Klassen haben n:n Beziehungen. Der Datenzugriff funktioniert. Nur die Frage der zuordnung stellt für mich ein Problem dar, was ich zwar gelöst habe, aber der Code sind durcheinander aus und ist zu kompliziert. Es muss ja eine einfacvhere Lösung geben:

Ich habe auf der linken Seite eine ListBox "User" auf der rechten eine ListBox "Shops". Die ListBox-Shop soll alle Elemente Shops enthalten., aber dem User zuzuordnen sein (mit CheckBox). Aber die Frage ist,w ie sieht die Bindung der ListBox "Shops" aus. bind ich an User.Shops werden natürlich nur die zugeordneten Elemente angezeigt. Binde ich direkt an Shops, fehlt mir die Möglichkeit, mit möglichst wenig Code, die Zuordnung herzustellen. Wie kann man das "elegant" lösen?

19.04.2013 - 19:24 Uhr

Ich habe das Galaxy S3, dass an sich ein tolles Handy ist. Leider finde ich es total langsam. Ob das an Android liegt kann ich nicht sagen. Nach einem Neustart ist es ja recht flott, aber wenn es eine Weile läuft wird es lahm. Es ist nervig, wenn die Kontaktliste schon 3 Sekunden lädt.

18.04.2013 - 15:10 Uhr

Also im Prinzip geht es in den meisten Beispielen darum den Dialog in der View zu erzeugen und an Properties zu binden. Nur die Frage die sich stellt, wie sinnvoll ist es die ganzen Properties einzusetzen für den Dialog? Ich rede hier über die Buttons, den Titel, den Content und natürlich auch den Result, den ich sowohl an einen ICommand binden kann oder auch als Property zurückgeben kann. Soll das der Sinn sein? Das Prinzip ist mir klar und im Moment teste ich das auch so. Aber als endgültige Lösung gefällt mir das nicht.

Andererseits könne ich aber eine Art DialogModel dazwischen setzen und dort die ganzen Properties reinpacken. Der DataContext zeigt dann auf das Model und ich brauche die ganzen Properties nicht in meinem "MainViewModel" drin zu haben. Ein Beispiel gab es ja dazu auch.

17.04.2013 - 18:16 Uhr

Klar wäre es einfacher. Allerdings war das hier nur ein Beispiel. Im Falle einer MessageBox müsste ich dann etliche Properties daran binden und ich finde das Ganze dann etwas unübersichtlich.

17.04.2013 - 13:39 Uhr

Sorry für das Missverständnis. Ich möchte bei dem Design des UserControls ohne MVVM arbeiten. Die Anwendung die das UserControl nutzt verwendet aber MVVM. Deshalb auch die Code-Beispiele.

17.04.2013 - 09:58 Uhr

In der Codebehind der View geht das, aber im ViewModel nicht. Macht ja auch keinen Sinn, da ich dann wohl den Sinn des MVVM-Patterns umgehe.

16.04.2013 - 21:30 Uhr

Ich wusste nicht so recht, wie ich das Thema nennen sollte. In einem eigenen UserControl, welches ich per XAML in mein View eingebunden habe möchte ich eine Methode aufrufen. Allerdings gestaltet das sich nicht so einfach, denn ich möchte nicht mit View und ViewModel arbeiten - zumindest innerhalb des Controls. Wie komme ich also an meine Methode ran ohne 2 Instanzen zu haben? Beispiel:

UserControl:


public class MyUserControl : UserControl
{
....
    public void Show()
    {
        this.Visibility = Visibility.Visible;
    }
}

Anwendung:

View:


<mycontrols:MyUserControl>

ViewModel:


...
myctrl = new MyUserControl();
myctrl.Show();

Geht natürlich nicht so, weil falsche Instanz. Wie bekomtm man das hin?

15.04.2013 - 11:28 Uhr

Ja das Problem an sich habe ich, dank deiner Tipps auch genauer nachvollziehen können. Das ChangedCallbacks wird nur dann ausgelöst, wenn tatsächlich der Wert des Properties sich ändert. Bei einem herkömmlichen Property kann ich das selbst entscheiden, indem ich value mit meinem Property Speicher vergleiche. Bei den DependencyProperties geht das so nicht. Demnach bleibt mir nur die Möglichkeit an anderer Stelle die Initialisierungen durchzuführen.

	
public static readonly DependencyProperty GalaMessageProperty =
			DependencyProperty.Register("GalaMessage", typeof(DialogMessage), typeof(MessageBoxDialog),
			new FrameworkPropertyMetadata(null, GalaMessagChangedCallback) { BindsTwoWayByDefault = true });

public static void GalaMessagChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			MessageBoxDialog dlg = (MessageBoxDialog)d;
			DialogMessage message = (DialogMessage)e.NewValue;
			if (message != null) {
				dlg.Text = message.Content;
				dlg.Caption = message.Caption;
				dlg.Icon = message.Icon;
				dlg.Button = message.Button;
				dlg.IsShown = true;
			} else {
				dlg.Text = null;
				dlg.Caption = null;
				dlg.IconImage = null;
				dlg.Commands = null;
				dlg.Button = new MessageBoxButton();
				dlg.IsShown = false;
			}
		}

Wenn sich GalaMessage nicht ändert, sondern nur deren Member, dann passiert hier nichts und das ist das Problem. Ich kann nur "intern" GalaMessage auf null setzen. Aber das gefällt mir nicht, das ja vom Nutzer des UserControls evtl. nicht gewünscht wird.

Möglicherweise kommt mir gerade die Idee das Property IsShown zu nutzen und genau dort alle Properties zu setzen, dann sollten die anderen Probleme vom Tisch sein. Hier wäre es allerdings besser nicht ein Changed, sondern ChangeCallback zu nutzen, um erst einmal alle anderen Properties zu setzen. So ein Property gibt es aber leider nicht.

15.04.2013 - 11:12 Uhr

.. oder alternativ 2 Textboxen nebeneinander. Hier ist eigentlich die Frage, was das für Texte sein soll, die ind er TextBox eingegeben werden sollen?

15.04.2013 - 07:37 Uhr

Ich habe ein eigenes UserControl geschrieben, welches DependencyPropertys hat. Eines eben dieser Properties mchte auch andere DependencyProperties setzen. Allerdings klappt dann das ChangedCallback dieser Properties nicht immer und zuverlässig. Gibt es da was zu beachten? Darf man diese DependencyProperties überhaupt "intern" beschreiben?

11.04.2013 - 13:10 Uhr

Danke für die Tipps. Ich glaube nachher ist die Sicherheit das größte Problem. 😉

Gibt es da Quellen zum Usermanagement? Denn grundsätzliches Usermanagement habe ich ja schon jetzt in der DB (lokal) eingebaut, sprich ich muss mich anmelden um die Daten zu sehen. Allerdings ist die Sicherheit in meiner Client-Anwendung und nicht in der Datenbank. Denn theoretisch könnte ich aktuell von außen auch ohne Anwendung auf die Daten zugreifen.

Im Grund wäre zu überlegen, ob der Aufwand lohnt ... die Entscheidung muss jetzt fallen, denn im einfachsten Fall habe ich nur eine Anwendung die mittels SQL-Server im lokalen Netzwerk laufen kann und so dennoch mehrere Nutzer zulässt. Mit Erweiterung des Netzwerkes über VPN wird die Reichweite sicherlich größer und ich muss mir nicht zu große Sorgen wegen der Sicherheit machen, da der VPN-Tunnel das absichert.

Die spannendste Variante ist sicherlich die Web-Lösung, auch wenn ich eine generelle Web-Plattform eigentlich vermeiden will und nur die Datenbank im Webspace hosten will. Aber sie ist zukunftsträchtiger und gibt mir die Möglichkeit die Anwendung auch für Silverlight und Mobile Geräte zu erweitern, was mit der "lokalen" Lösung nicht machbar ist. Dem entgegen steht wieder ein höheres Sicherheitsrisiko.

10.04.2013 - 22:42 Uhr

Aber was ist denn mit den ganzen tollen Anwendungen (CMS), die direkt im Internet laufen? Da werden doch die Daten auch irgendwo auf einem Web-Server gespeichert und die Sicherheit läuft mittels Verschlüssung und Zugangsdaten.

Wäre hier nicht die Lösung einfach eine WebSite mit Datenbank zu mieten (Hosting-Anbieter gibts ja genug), die NET-Anwendung mit einer lokalen Datenbank z.B. SQL-Server Compact zu betreiben und die notwendigen Daten dann ins Web und zurück zu synchronisieren?

Folgende Vorteile (für mich) hätte die Lösung:

  • unabhängig von einem eigenen Server oder anderer Hardware ink. VPN
  • MultiUser-Fähigkeit integrierbar, dass heißt verschiedene Unternehmen kämen mit Zugangsdaten + individuelle Nutzerlogins nur an ihre Daten ran
  • die Synchronisation kann als Option realisiert werden -> brauche ich das nicht läuft die Datenbank halt nur lokal

Geht das so? Ist das so realisierbar? Wäre die Sicherheit hier ein Problem?

09.04.2013 - 15:42 Uhr

Entschuldigung, dass ich mich nicht ganz klar ausgedrückt habe. Ja, es geht um eine verteilte Anwendung, also eine Anwendung, die mehrere Clients für den Datenzugriff besitzt und die Daten sollen entweder Zentral oder verteilt gespeichert werden, aber überall synchron sein. Die Umsetztung war, wie schon im Titel benannt mit dem SyncFramework gedacht .. nur ist halt die Frage ob das überhaupt sinnvoll ist. Da die Daten möglichst zeitnah aktuell sein sollen und der Datenzugriff auch recht flott sein soll. Es geht hauptsächlich um Textdaten und u.U. kleine Bilder.

Die VPN-Verbindung inkl. IP-Netz stellt bei mir die Fritz!Box her. Allerdings kann nicht bei jedem Nutzer der Anwendung vorausgesetzt sein, dass eine Fritz!Box, geschweige denn ein VPN-Netzwerk vorhanden ist.

Wenn ich es richtig verstanden habe, ist der Weg der Synchronisation und nicht der des direkten Zurgiffs empfohlen? Und auch dazu benötige ich eine "feste IP"?

08.04.2013 - 19:20 Uhr

Ich möchte gern Datenbanken synchronisieren. Ich habe, glaueb ich verstanden wie das funktioniert. Dazu gibt es ja bei Microsoft genug Informationen. Allerdings bin ich nicht sicher, ob die Lösung die optimale ist, denn verschiedene Szenarien haben ja ihre Vor- und Nachteile:

  1. Synchronisierung mehrerer "Niederlassungen" über VPN:
  • Vorteil: einfach zu bewerkstelligen, Offline möglich
  • Nachteil: VPN-verbindung muss eingerichtet werden, was für eine gängige Anwendung kompliziert sein könnte
  1. Synchronisierung über Internet:
  • Vorteil: nichts einzurichten, Anwendung installieren und fertig
  • Nachteil: man braucht irgednwie eine Internetadresse - WCF-Service?
  • Frage: Was muss der Web-Anbieter bereitstellen? Gibt es kostenlose Lösungen? Lassen sich verschiedene Datenbank von verschiedenen Anwendern über eine Web-Site abwickeln?
  1. direkter Zugriff auf einem SQL-Server:
  • Vorteil: einfach zu installieren, keine Synchronisierung erforderlich, konsistente Daten
  • Nachteil: VPN erforderlich, stetige Verbindung nötig, evtl. langsam

Wie sieht ihr das Ganze. Könnt ihr mir Tipps geben? DANKE!!!

08.04.2013 - 19:13 Uhr

@tabstop: Aber spätestens dann, wenn ich die Daten synchronisieren will, habe ich mit der normalen INT ein Problem ..... sonst würde ich mir die Mühe mit der GUID nicht machen...

02.04.2013 - 23:09 Uhr

Ich habe hier eine View, wo ich noch ein zusätzliches Control einbaue. Wenn ich das Control anzeigen lasse (Visibility), dann wird der Hintergrund usgegraut und das UsrCOntrol ist sichtbar. Allerdings lässt sich die Tab-Taste trotzdem durch alle COntrols bewegen. Wie kann ich das vermeiden?

02.04.2013 - 23:03 Uhr

@SuperVisor:
Das bedeutet aber auch, dass Du jede neue Entität per Hand zufügen musst?! Das macht für mich der EntityBuilder oder wie der heißt aus dem ETF 5.

Hand anlegen muss man aber dennoch, denn einige Sachen muss man sowieso zufügen, z.B. IDataErrorInfo.

31.03.2013 - 20:59 Uhr

Um das zu finden, muss man schon ein bisschen länger suchen und probieren, denn auch die Lösungsvorschläge funktionierten nicht so recht. Aber die Lösung ist denkbar einfach und jetzt geht es. Allerdings kann ich das nur fürs Entity Framework 5 bestätigen:

Das Property "StoreGeneratedPattern" der Identitätsspalte muss manuell auf "Identity" eingestellt werden. Dann geht es auch.

30.03.2013 - 18:35 Uhr

verwendetes Datenbanksystem: SQL-Server 2012, Entity Framework 5.0

Ich wollte meien Datenbank in Vorbereitung auf ein verteiltes System mit GUIDs umstellen. Allerdings funktioniert das Ganze nicht wie erwartet.

CREATE TABLE [dbo].[Employees] (
    [EmployeeId]  UNIQUEIDENTIFIER DEFAULT (newsequentialid()) NOT NULL,
    [LastName]    VARCHAR (50)     NULL,
    [FirstName]   VARCHAR (50)     NULL,
    .....

Die Id ist immer "00000000-0000-0000-0000-000000000000", wenn die Datenbank vom Framework beschrieben wird. Manuell geht es. Demnach kann ich davon ausgehen, dass newsequentialid() und auch newid() nicht funktioniert und ich die Id manuell generieren muss? Oder gibt es eine andere Lösung mit dem ETF.

30.03.2013 - 00:23 Uhr

Das "IsSynchronisizedWithCurrentItem" macht doch nichts anderes als das CurrentItem immer mit der angebundenen Quelle, also in meinem Fall der ICollectionView zu synchronisieren.

Ich habe aber das Problem, dass ich so ein DetailView habe und die Details bearbeiten will. In diesem Fall ist hier "Name" der "DisplayMember" und wenn ich diese ändere soll das auch in der ComboBox zu sehen sein - idealerweise direkt bei der Eingabe. Es geht aber nicht - erst nach einem kompletten Reload.