Mittwoch, 30. September 2009

ValidationErrors in xaml Controls

Validation auf xaml-controls findet man "überall" im Netz.. z.B. kann man das so machen:
<Binding Path="Person" 
         Mode="TwoWay">
 <Binding.ValidationRules>
  <ui:PersonValidationRule />
 </Binding.ValidationRules>
</Binding>
Nun habe ich aber keine möglichkeit auf einem Window sowas zu machen wie Window.ChildsHaveErrors(). Aus dieser Lage hilft das Folgende:
<Window [blah...]
  Validation.Error="ValidationError">

<Binding Path="Person" 
         Mode="TwoWay"
   NotifyOnValidationError="True">
    <Binding.ValidationRules>
        <ui:PersonValidationRule />
    </Binding.ValidationRules>
</Binding>
und im Code-Behind:
private int errorsInForm;
private void ValidationError(object sender, ValidationErrorEventArgs e)
{
   switch (e.Action)
   {
      case ValidationErrorEventAction.Added:
         this.errorsInForm++;
         break;
      case ValidationErrorEventAction.Removed:
         this.errorsInForm--;
         break;
   }
}
private bool WindowHasErrors
{
   get
   {
      return this.errorsInForm>0;
   }
}
  • Auf der Window-Deklaration im xaml den Validation.Error-Event setzten (Validation.Error ist übrigens eine "attached dependency property", sollte also auf fast allen Elementen funktionieren...)
  • Auf der Binding-Deklaration NotifyOnValidationError auf true setzen, damit wird der Fehler aus dem eigentlichen Element auf dem dieser entsteht hinaus "gebubbelt" (z.B. bis zum Window...)
  • Im Code-Behind, im ValidationError-EventHandler werden einfach die entstandenen Fehler gezählt (ValidationErrorEventAction.Removed ist ein "ehemaliger Fehler"...)
  • In WindowHasError wird dann nur noch geprüft, ob die aktuelle Zahl der Fehler größer ist als 0.
Meinungen dazu ?

VS2008 benötigt CLR-Typen von MS SQL 2008

Ich habe leztens alles deinstalliert, das "*SQL*2008*" im Namen hatte, und meinen SQL-Server 2005 DeveloperED wieder installiert.
Ein paar Tage später musste ich feststellen, dass DB-Verbindungen mit meinem VS2008 nicht mehr möglich waren.Der Fehler war: "Could not load file or assembly: Microsoft.SqlServer.Management.Sdk.Sfc in Visual Studio 2008 Server Explorer"


Lange Rede, kurzer Sinn: VS2008 benötigt für die DB-Verbindungen:
  • Microsoft SQL Server 2008 Management Objects (SMO) und
  • Microsoft SQL Server System CLR Types 
Beides gibts zum Download bei Microsoft.
Nachdem ich mir die Finger wund gesucht hatte um der Lösung auf die Schliche zu kommen habe ich auch diesen Post gefunden, der das gleiche Problem beschreibt.

Verschiedene Implementationen des selben Interfaces mit Unity "injecten"

PersonRepository und VorgangRepository sind zwei Implementationen eines Interfaces: IRepoistory
Um nun meinen DBAdapter, der (natürlich IDBAdapter implementiert und) beide IRepositories als parameter (natürlich in der richtigen Reihenfolge...) benötigt (Ob das eine tolle Idee war sei mal dahin gestellt.) instanziieren zu können, habe ich folgendes gemacht:
IUnityContainer container = UnityContainerProvider.UnityContainer;
container.RegisterType<IDbAdapter, DbAdapter>();
container.RegisterType<IRepository, PersonRepository>("Person");
container.RegisterType<IRepository, VorgangRepository>("Vorgang");
container.Configure<InjectedMembers>().ConfigureInjectionFor<DbAdapter>(
 new InjectionConstructor(
  new ResolvedParameter<IRepository>("Person"),
  new ResolvedParameter<IRepository>("Vorgang")
  ));
  • Configure() - Ich will die Member der Injection steuern...
  • ConfigureInjectionFor() - auf den DBAdapter instanzen
  • new InjectionConstructor() - der Konstruktor soll gesteuert werden
  • new ResolvedParameter("Person") - IRepository soll mit dem Key "Person" aufgelöst werden.
Etwas störend finde ich die Notwendigkeit dies über zwei Strings zu steuern, also wenn jemand eine bessere Idee hat.. Immer her damit.

Edit: Etwas besser ist natürlich das IRepository noch zwei mal abzuleiten (wenn dies möglich ist...) einmal als
IPersonenRepository und einmal als IVorgangsRepository.

Dienstag, 15. September 2009

Da in meiner Firma mit Outlook gearbeitet wird, habe ich auch meine Aufgaben in Outlook organisiert.
Nun habe ich bisher immer das Feature „Eine Aufgabe aus dieser Mail erstellen” vermisst.
Folgendes VBA-Makro habe ich nun dafür erstellt:
Option Explicit
Public Sub Mail2Task()
Dim olTask As Outlook.TaskItem
Dim olMail As MailItem
Dim olIns As Inspector
Dim olExp As Explorer
Set olTask = Application.CreateItem(olTaskItem)
Set olExp = Application.ActiveExplorer

If olExp.Selection.Count <> 1 Then
MsgBox "Funktioniert nur mit genau einer E-Mail"
Exit Sub
End If

If Not TypeOf olExp.Selection.Item(1) Is Outlook.MailItem Then
MsgBox "Funktioniert nur mit E-Mails !"
Exit Sub
End If

Set olMail = olExp.Selection.Item(1)
With olTask
.Subject = olMail.Subject
.Body = olMail.Subject & vbCrLf & vbCrLf
.StartDate = Now
.DueDate = DateAdd("d", 7, Date)
.ReminderSet = False
.Status = olTaskInProgress
End With
olTask.Attachments.Add olMail
Set olIns = olTask.GetInspector
olIns.Display ("True")
End Sub

Das Makro erstellt aus einer selektierten eMail eine folgende Aufgabe:
  • Betreff der Aufgabe entspricht dem Betreff der eMail
  • Text der Aufgabe enthält noch einmal den Betreff der eMail sowie die eigentliche Mail als Anhang.
  • Start der Aufgabe ist sofort
  • Termin (Ende) ist in 7 Tagen
  • Status ist „In Progress”
Anschließend wird die Aufgabe zur Bearbeitung (Termin-anpassung, Wichtigkeit, etc.) geöffnet.

Samstag, 5. September 2009

Anfängergeschwindigkeit

Ich habe über mein neues neo-layout berichtet. Nun habe gerade den schnell-schreiben-speedtest gefunden.

15 WörterZum Vergleich : Mit Qwerz waren es etwa 29 Wörter/min bei ca. 180 Zeichen — auch kein Blumentopf mit zu gewinnen...

Freitag, 4. September 2009

SVDRP mit C#

Ich habe diese Woche mein erstes Google-Code Projekt gestartet.
Das Ziel von SvdrpNet ist mehrfach:
  1. Ich wollte eine kleine GUI, um SVDRP-Anfragen zu versenden und die Ergebnisse darzustellen.
  2. Ich wollte eine GUI um die Timer meiner beiden modifizierten M740AV zu betrachten und (und dies ist der Punkt, den mir bisher keine andere Software bieten konnte:) um die Timer von einem Gerät auf ein anderes kopieren.
Schließlich habe ich mich für vier kleine Teilprojekte entschieden: Zusätzlich zu den oberen Zweien noch
  1. Ein kleines Kommandozeilentool, analog zu i.
  2. Eine „Wrapper-Lib“ für die SVDRP-Zugriffe.
Die Minimalfunktionen von iv., iii. und i. sind bereits fertig gestellt.
Das Projekt findet sich unter : http://code.google.com/p/svdrpnet/
Eine entsprechende Diskussionsgruppe habe ich unter http://groups.google.com/group/svdrpnet eingerichtet.

Neo-layout

Ich habe es getan.. In der letzten Woche hat meinen neuer Rechner endlich seinen Dienst aufgenommen. Dabei habe ich gleich alles (Konsole und X) mit dem neo2 Tastatur-Layout versehen.
Einen Tag später war ich so ziemlich am Ende und wollte das Layout schon wieder wechseln...
Statt dessen habe ich meinen Dymo bemüht und mir eine passende neo2 Tastatur geschaffen.




Aktuell macht das ganze einen eher „miesen“ Eindruck. Aber das Tippen macht wieder Spaß. Vielleicht schaffe ich es ja auch das Ganze etwas zu verbessern.. (Also weniger mit dem Dymo arbeiten, dafür mehr mit einem Farblaser...)