1

C#で小さなチャットアプリケーションを作成し、コンソールアプリケーションとして開始しました。ただし、WPFを使用してGUIを作成したいと思います。これは、、DanMessengerClientなどの関数で名前が付けられたクラスです。InitializeConnection()SendMessage(string msg)

私はすでにVisualStudioでUIを設計しておりWindow1、デフォルトでWindow1.xaml.csにそのクラスを作成しました。現在、テキストエリアにダミーテキストのみを追加する[送信]ボタンのイベントハンドラーを作成しました。私の質問は、WIndow1クラスからSendMessage()関数をどのように呼び出す必要があるかということです。

そのクラスでオブジェクトを作成しようとしましたが、最初のクラス内からテキストボックスにアクセスする必要があるため(つまり、メッセージを受信したら、テキストボックスを更新します)、Window1クラスへの参照を追加すると、StackOverflow作成が継続されるため、例外がスローされます。無限ループ内の参照。

GUIアプリケーションは初めてです。どうすればいいですか?

4

2 に答える 2

3

WPF でデータを表示する標準的な方法は、コントロールをそれにバインドすることです ( MSDN のデータ バインディングを参照してください)。これにはおそらく、メッセンジャー クラスをラップまたはリファクタリングして、バインド可能なプロパティを公開する必要があります。たとえば、メッセンジャー クラスは、メッセージを受信するたびに更新する MessageText というプロパティを公開する場合があります。

// 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;
}

ここで、TextBox.Text プロパティをこの新しいプロパティにバインドします。

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

これは、ウィンドウがメッセンジャーを作成するときなど、メッセンジャー オブジェクトがウィンドウの DataContext として設定されていることを前提としています。

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

これが機能するには、メッセンジャー クラスに INotifyPropertyChanged を実装する必要があることに注意してください。また、ユーザーが TextBox を編集した場合に MessageText プロパティが台無しにならないように、OneWay バインディングにも注意してください。(ユーザーがまったく編集できないように、TextBlock を使用することもできます。)

この設定が完了すると、WPF は _myMessenger.MessageText プロパティの変更を自動的に監視し、発生したときに (つまり、メッセージを受信すると) TextBox.Text を更新します。

最後に、送信方法について: テキストを渡すだけです:

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

Name 属性を使用して、送信するメッセージを含むテキスト ボックスに名前を付けます。

<TextBox Name="MyTextBox" />
于 2009-10-24T22:39:49.603 に答える
0

itowlson が言っていることを少し拡張すると、次のようになります。

次のようなインターフェイスを作成することから始めます。

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

このインターフェイスを実装するクラスの動作は非常に単純です。メッセージが受信されると、MessageBuffer(おそらく改行が先行する) に追加されます。メッセージを送信するには、 を設定MessageToSendして呼び出しますSendMessage()。これにより、送信されたメッセージが にも追加されますMessageBuffer。これを単純にするためにスキップしている実装の詳細がたくさんあります。

IMessagingClient次に、 と を実装したテスト クラスを作成しINotifyPropertyChangedます。このクラスは、実際に何かを行う必要はありません。ほとんどの場合、ランダムな間隔でランダムなテスト メッセージを生成し、更新しMessageBufferます。また、SendMessageが呼び出されると、 がクリアMessageToSendされて更新されMessageBufferます。

次に、コードをウィンドウに追加して、このクラスのインスタンスを作成し、それに設定DataContextします。TextBoxアウトバウンドをMessageToSendに、インバウンドTextBlockをにバインドしMessageBuffer、 を に接続しButtonますSendMessage

UI がテスト オブジェクトに対して機能するようになったら、同じインターフェイスを実装する別のクラスを作成します。このクラスだけDanMessengerClientが、プロパティ セッターが相互運用するプライベート オブジェクトを作成します。次に、代わりにウィンドウにこのオブジェクトのインスタンスを作成させます。

実際のメッセージング クライアントは、おそらくより洗練されたものになる必要がありLastMessageReceivedますToolTip。また、MessageBufferプロパティは実際には何らかの方法でリッチ テキストをサポートする必要がある場合があります。しかし、これは良い出発点です。

于 2009-10-24T23:42:30.537 に答える