繁体   English   中英

将控制台应用程序移植到WPF

[英]Porting a console application to WPF

我已经用C#创建了一个小型的聊天应用程序,并开始作为一个控制台应用程序。 但是我想使用WPF为它创建一个GUI。 这是一个名为DanMessengerClient的类,具有诸如InitializeConnection()SendMessage(string msg)等功能。

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

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

我是GUI应用程序的新手。 我应该如何进行?

WPF中显示数据的规范方法是将控件绑定到该控件(请参阅MSDN中的数据绑定 )。 这可能需要包装或重构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,例如,当窗口创建Messenger时:

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

使用“名称”属性为包含要发送的消息的文本框命名:

<TextBox Name="MyTextBox" />

只是为了扩展一下itowlson所说的话:

我将从创建这样的接口开始:

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

实现此接口的类的行为应该非常简单。 收到消息后,它将被添加到MessageBuffer (可能在换行符之后)。 要发送消息,请设置MessageToSend并调用SendMessage() ,这还将发送的消息添加到MessageBuffer 为了简化起见,我跳过了很多实现细节。

接下来,我将构建一个实现IMessagingClientINotifyPropertyChanged的测试类。 此类实际上不需要做任何实际的事情:它很可能仅以随机间隔生成随机测试消息并更新MessageBuffer 同样,在调用SendMessage时,它将清除MessageToSend并更新MessageBuffer

然后,将代码添加到窗口中以创建此类的实例并将DataContext设置为该实例。 我将出站TextBox绑定到MessageToSend ,将入站TextBlock绑定到MessageBuffer ,并连接一个Button来调用SendMessage

一旦使UI与测试对象配合使用,我将构建另一个实现相同接口的类,只有该类才能创建一个私有的DanMessengerClient对象,该属性与设置程序进行交互。 然后,我将使窗口创建该对象的实例。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM