我在C#中创建了一个小型聊天应用程序,并作为控制台应用程序启动。但是我想使用WPF为它创建一个GUI。它是一个名为 DanMessengerClient 的类,其函数包括 InitializeConnection() SendMessage(string msg)等。

我已经在Visual Studio中设计了UI,默认情况下它在Window1.xaml.cs上创建了它的 Window1 类。我为“发送”创建了一个事件处理程序。现在只将一些虚拟文本附加到textarea的按钮。我的问题是,我应该如何从WIndow1类调用SendMessage()函数?

我尝试在该类中创建对象,但由于我还需要从第一个类内部访问Textbox(即,当我收到消息,更新文本框时),添加对Window1类的引用会抛出 StackOverflow 异常,因为它一直在无限循环中创建引用。

我是GUI应用程序的新手。我该怎么办?

有帮助吗?

解决方案

WPF中用于显示数据的规范方法是将控件绑定到它(请参阅数据绑定”。这可能需要您包装或重构您的messenger类,以便它暴露可绑定属性。例如,您的messenger类可能会公开一个名为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}" />

这假设将messenger对象设置为窗口的DataContext,例如当窗口创建信使时:

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

请注意,您的messenger类必须实现INotifyPropertyChanged才能生效。还要注意OneWay绑定,这样如果用户编辑TextBox,它就不会破坏MessageText属性。 (您也可以使用TextBlock,以便用户根本无法编辑它。)

当您完成此设置后,WPF将自动监视_myMessenger.MessageText属性中的更改,并在发生时更新TextBox.Text(即收到消息时)。

最后,关于如何进行发送:只需传递文字:

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

使用Name属性命名包含要发送的消息的文本框:

<TextBox Name="MyTextBox" />

其他提示

只是为了扩大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 ,并挂钩按钮来调用 SendMessage

一旦我使用了针对我的测试对象的UI,我就会构建另一个实现相同接口的类,只有这个接口会创建属性设置器与之互操作的私有 DanMessengerClient 对象。然后我会让我的窗口创建一个这个对象的实例。

实际的消息传递客户端可能需要更复杂。例如,您可能希望实现 LastMessageReceived 属性,以便您可以对该文本执行特殊操作,例如将其放入一个 ToolTip 。并且 MessageBuffer 属性实际上可能需要以某种方式支持富文本。但这是一个很好的起点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top