Question

J'ai créé une petite application de discussion en C # et démarré en tant qu'application console. Cependant, je souhaite créer une interface graphique à l'aide de WPF. C'est une classe nommée DanMessengerClient avec des fonctions telles que InitializeConnection () , SendMessage (string msg) , etc.

J'ai déjà conçu l'interface utilisateur dans Visual Studio, qui a créé sa classe Window1 sur Window1.xaml.cs par défaut. J'ai créé un gestionnaire d'événements pour l'option "Envoyer". bouton qui ajoute seulement du texte factice à une zone de texte dès maintenant. Ma question est la suivante: comment appeler la fonction SendMessage () de la classe WIndow1?

J'ai essayé de créer l'objet dans cette classe, mais comme je dois également accéder à la zone de texte depuis la première classe (par exemple, lorsque je reçois un message, mettez à jour la zone de texte), l'ajout de la référence à la classe Window1 renvoie un code < > StackOverflow car il continue de créer des références dans une boucle infinie.

Je suis nouveau dans les applications graphiques. Comment dois-je procéder?

Était-ce utile?

La solution

La manière la plus courante d’afficher des données dans WPF consiste à lui lier un contrôle (voir Liaison de données dans MSDN). Cela nécessiterait probablement que vous encapsuliez ou reformuliez votre classe de messagerie afin qu'elle expose des propriétés pouvant être liées. Par exemple, votre classe de messagerie peut exposer une propriété appelée MessageText, que vous mettez à jour à chaque fois que vous recevez un message:

// INotifyPropertyChanged interface implementation and plumbing

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
  if (PropertyChanged != null)
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName);
}

// The property you are going to bind to

private string _messageText = String.Empty;

public string MessageText
{
  get { return _messageText; }
  set
  {
    _messageText = value;
    OnPropertyChanged("MessageText");
  }
}

// How to modify your code to update the bindable property

private void OnMessageReceive(string message) // assuming this method already exists
{
  MessageText = MessageText + Environment.NewLine + message;
}

Maintenant, vous lieriez la propriété TextBox.Text à cette nouvelle propriété:

<TextBox Text="{Binding MessageText, Mode=OneWay}" />

Cela suppose que l'objet messenger est défini en tant que DataContext de la fenêtre, par exemple. lorsque la fenêtre crée le messager:

public class Window1()
{
  _myMessenger =  = new DanMessengerClient();
  this.DataContext = _myMessenger;
}

Notez que votre classe de messagerie doit implémenter INotifyPropertyChanged pour que cela fonctionne. Notez également la liaison OneWay afin que, si l'utilisateur modifie la zone de texte, il ne gâche pas la propriété MessageText. (Vous pouvez également utiliser un TextBlock afin que l'utilisateur ne puisse pas le modifier du tout.)

Une fois cette configuration configurée, WPF surveille automatiquement les modifications apportées à la propriété _myMessenger.MessageText et met à jour le TextBox.Text au fur et à mesure de leur apparition (c'est-à-dire à la réception des messages).

Enfin, en ce qui concerne la procédure d'envoi: il suffit de passer le texte:

private void SendButton_Click(...)
{
  _myMessenger.Send(MyTextBox.Text);
}

Utilisez l'attribut Nom pour nommer la zone de texte contenant le message à envoyer:

<TextBox Name="MyTextBox" />

Autres conseils

Juste pour développer un peu ce qu’itowlson dit:

Je commencerais par créer une interface comme celle-ci:

interface IMessagingClient
{
    string MessageToSend { get; set; }
    string MessageBuffer { get; }
    void SendMessage();
}

Le comportement des classes implémentant cette interface devrait être assez simple. Lorsqu'un message est reçu, il est ajouté à MessageBuffer (probablement précédé d'une nouvelle ligne). Pour envoyer un message, définissez MessageToSend et appelez SendMessage () , qui ajoute également le message envoyé à MessageBuffer . Je saute beaucoup de détails sur la mise en œuvre pour que cela reste simple.

Ensuite, je construirais une classe de test qui implémenterait IMessagingClient et INotifyPropertyChanged . En réalité, cette classe ne doit rien faire de réel: elle produira probablement des messages de test aléatoires à des intervalles aléatoires et mettra à jour MessageBuffer ; De même, lorsque SendMessage est appelé, il efface MessageToSend et met à jour MessageBuffer .

J'ajouterais alors du code à ma fenêtre pour créer une instance de cette classe et y définir le DataContext . Je lierais mon TextBox sortant à MessageToSend et mon TextBlock entrant à MessageBuffer , et raccorderais un Bouton pour appeler SendMessage .

Une fois que l'interface utilisateur fonctionnait contre mon objet test, je construisais une autre classe qui implémentait les mêmes interfaces. Seul celui-ci créerait un objet privé DanMessengerClient avec lequel les régleurs de propriété interagiraient. Alors je ferais ma fenêtre créer une instance de cet objet à la place.

Un client de messagerie réel devra probablement être plus sophistiqué. Par exemple, vous pouvez implémenter une propriété LastMessageReceived afin de pouvoir faire quelque chose de spécial avec ce texte, comme le mettre dans une info-bulle . Et la propriété MessageBuffer pourrait en réalité avoir besoin de prendre en charge le texte enrichi d'une manière ou d'une autre. Mais c’est un bon point de départ.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top