2009-10-06 8 views
1

J'essaie de refactoriser mon projet de sorte qu'au lieu de nombreuses fonctions, j'aurais plutôt des objets. Je suis en train d'écrire une application qui communique avec un scanner optique spécifique via le port série. (Write, Open, Close) et certaines méthodes avancées, qui ne sont pas incluses dans la classe standard, comme ActivateLaser (elle écrit des octets spécifiques sur SerialPort).Bibliothèque de liens dynamiques pour scanner optique

J'ai fait la première étape: J'ai créé une nouvelle classe, qui hérite de la classe SerialPort et ajouté mes propres méthodes, comme ActivateLaser. Ce projet est compilé en DLL puis inclus dans mon projet principal.

Maintenant, je voudrais aller plus loin et inclure également l'écoute de SeiralPort à ma DLL. Comment ça marche maintenant: tout d'abord j'attribue événement DataReceived à mon scanner (scanner est par exemple de ma propre classe SerialPort):

scanner.DataReceived += MyDataReceivedEventHandler; 

Ensuite, dans le MyDataReceivedEventHandler j'appelle un délégué, qui affiche les données reçues dans RichTextBox ou DataGridView:

private void MyDataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    ... 
    this.BeginInvoke(new DisplayDataDelegate(DisplayData), receivedText); 
    ... 
} 

private void DisplayData(string receivedText) 
{ 
    // display received text in RichTextBox in one project, display received text in DataGridView in another project 
} 

Maintenant, je me demande comment mettre en œuvre l'écoute de port série dans la classe MySerialPort. Si je viens d'ajouter gestionnaire d'événements pour DataReceived, then qui lie MyDataReceivedEventHandler à scanner, ressemblerait à quelque chose comme ceci:

scanner.DataReceived += scanner.MyDataReceivedEventHandler; 

Je ne sais pas comment mettre tout cela ensemble (dois-je définir MyDataReceivedEventHandler en classe MySerialPort , où devrais-je mettre délégué pour l'affichage du texte, comment puis-je rendre possible, pour afficher du texte dans RichTextBox ou dans DataGridView, ...)

Je sais que ma question est un peu complexe, mais j'aimerais vraiment organiser mon travailler mieux, afin que je puisse utiliser ma classe MySerialPort dans d'autres projets ...

Merci!

Répondre

1

Je suggère d'élever un événement personnalisé dans votre implémentation de SerialPort. Cet événement peut contenir des données transmises à la couche d'interface utilisateur de votre application où vous pouvez l'afficher dans un RichTextBox. Cela va séparer la classe du scanner des contrôles de l'interface utilisateur et signifie que vous n'avez pas besoin d'avoir une référence à RichTextBox dans votre classe de scanner.

À titre d'exemple, vous pouvez créer un événement personnalisé appelé DocumentScanned et une classe dérivée de EventArgs appelée DocumentScannedEventArgs pour contenir les données d'événement.

Dans votre implémentation SerialPort, vous pouvez gérer l'événement DataReceived et, à son tour, déclencher un événement DocumentScanned lorsque vous recevez de nouvelles données. Votre interface utilisateur peut s'abonner à cet événement pour recevoir le texte numérisé et l'afficher comme bon vous semble.

Quelque chose le long des lignes de (en supposant que vous utilisez C# 3.0):

public class DocumentScannedEventArgs : EventArgs 
{ 
    public DocumentScannedEventArgs(string scannedText) 
    { 
     ScannedText= scannedText; 
    } 

    public string ScannedText { get; set } 
} 

... 

public class MySerialPort : SerialPort 
{ 
    public MySerialPort() 
    { 
     ... 
     this.DataReceived += scanner.MyDataReceivedEventHandler; 
     ... 
    } 

    ... 

    public event EventHandler<DocumentScannedEventArgs> DocumentScanned; 

    protected void OnDocumentScanned(DocumentScannedEventArgs e) 
    { 
     var handler = DocumentScanned; 

     if (handler != null) 
     { 
      handler(this, e); 
     } 
    } 

    private void MyDataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e) 
    { 
     ... 
     this.BeginInvoke(new DisplayDataDelegate(DisplayData), receivedText); 
     ... 
    } 

    private void DisplayData(string receivedText) 
    { 
     // fire DocumentScanned event 
     OnDocumentScanned(new DocumentScannedEventArgs(receivedText)); 
    } 
} 
+0

j'oublié de mentionner - je l'utilise .NET 2.0, que dois-je changer pour le faire fonctionner dans mon exemple ? – sventevit

+0

Vous aurez juste besoin de changer la propriété ScannedText dans DocumentScannedEventArgs (j'ai utilisé les propriétés automatiques C# 3.0). Pour C# 2.0 vous utiliseriez un champ de sauvegarde et le liriez/assigneriez à celui-ci dans le getter et les setters de ScannedText. – dariom

+0

Merci :) Encore une question: si je mets tout ça dans ma classe, alors ceci.InscriptionBin n'existe pas. De quel espace de noms dois-je utiliser la méthode BeginInvoke? – sventevit

Questions connexes