2009-10-24 10 views
1

C#으로 작은 대화 응용 프로그램을 만들고 콘솔 응용 프로그램으로 시작했습니다. 그러나 WPF를 사용하여 GUI를 만들고 싶습니다. 그것은 내가 이미 Visual Studio에서 UI를 디자인 한 같은 InitializeConnection(), SendMessage(string msg) 등의 기능을 DanMessengerClient라는 이름의 클래스 등콘솔 응용 프로그램을 WPF로 이식

, 그리고 그것은 기본적으로 Window1.xaml.cs에 Window1 클래스의 만들었습니다. "보내기"버튼에 대한 이벤트 핸들러를 만들었습니다.이 버튼은 현재 텍스트 영역에 더미 텍스트 만 추가합니다. 내 질문은 WIndow1 클래스에서 SendMessage() 함수를 어떻게 호출해야합니까?

그 클래스에서 개체를 만들려고했는데, 첫 번째 클래스 내부에서 TextBox에 액세스해야하므로 (즉, 메시지를받을 때 텍스트 상자를 업데이트 할 때) Window1 클래스에 대한 참조를 추가하면 StackOverflow은 무한 루프에서 참조를 계속 생성하기 때문에 예외입니다.

저는 GUI 응용 프로그램을 처음 사용합니다. 어떻게해야합니까?

+1

왜 수업 내에서 텍스트 상자가 필요합니까? 수업은 데이터 처리/결과 만 제공하고 GUI는 datta 및 결과 만 나타냅니다. 예를 들어, 단추 처리기에서 myMessengerClass.SendMessage (textBoxMessage.Text)를 사용합니다. SendMessage 메서드는 메신저 클래스의 텍스트 상자가 필요하지 않은 방식으로받은 텍스트를 처리하는 방법을 알아야하며 해당 텍스트 만 사용해야합니다. – Carlo

답변

3

WPF에서 데이터를 표시하는 표준 방법은 컨트롤을 바인딩하는 것입니다 (MSDN의 Data Binding 참조). 이것은 아마도 당신이 메신저 클래스를 랩핑하거나 리팩토링하여 바인딩 가능한 속성을 노출 할 것을 요구할 것입니다.

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

메시지를 포함하는 텍스트 상자에 이름을 이름 속성을 사용하여 확인할 수 있습니다 :

<TextBox Name="MyTextBox" /> 
+0

클래스는 매우 작습니다. 편집하는 데 아무런 문제가 없습니다. 나는 어떻게 바인딩이 나를 도울 수 있는지 이해하지 못합니다. 텍스트 상자에 문자열을 추가하는 방법에 대한 예제를 보여 주시겠습니까? –

+0

메시지를 받았을 때 클래스에 이미 코드를 가지고 있다고 가정합니다. MessageText라는 새로운 속성을 처음에는 빈 문자열로 만듭니다. 이제 수신 코드에서 MessageText에받은 텍스트를 추가하고 MessageText에 대한 PropertyChanged 이벤트를 발생시킵니다. 이것으로 수업에 대한 변경이 완료되었습니다. 이제 XAML에서 위에 표시된 것처럼 TextBox 바인딩과 창 DataContext를 설정합니다. 이제 클래스가 MessageText를 업데이트 할 때마다 WPF는 PropertyChanged 이벤트를 확인하고 자동으로 TextBox를 업데이트합니다. 자세한 내용을 표시하도록 수정하겠습니다. – itowlson

+0

좋아요, 코드를 업데이트했습니다. TextBox에 문자열을 추가하지는 않습니다. 데이터 모델 *의 속성 *에이 속성을 추가하려고합니다. 텍스트 상자에 자동으로 반영됩니다. 이것은 관용적 인 WPF이며 _myMessenger가 Window1 또는 TextBox에 대한 참조를 갖도록해야합니다. – itowlson

0

만에 itowlson이 말하는 내용을 조금 더 확장하십시오 :

다음과 같은 인터페이스를 만들어서 시작하겠습니다 :

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

이 인터페이스를 구현하는 클래스의 동작은 매우 간단해야합니다. 메시지가 수신되면 MessageBuffer에 추가됩니다 (아마도 개행이 선행됩니다). 메시지를 보내려면 MessageToSend을 설정하고 SendMessage()으로 전화하십시오. 그러면 메시지가 MessageBuffer에 추가됩니다. 이 간단한 유지를 위해 건너 뛰는 구현 세부 사항이 많이 있습니다.

다음으로 IMessagingClientINotifyPropertyChanged을 구현 한 테스트 클래스를 작성합니다. 이 클래스는 실제로 아무 것도 할 필요가 없습니다. 임의의 간격으로 무작위 테스트 메시지를 생성하고 MessageBuffer을 업데이트 할 가능성이 큽니다. 또한 SendMessage이 호출되면 MessageToSend 및 업데이트 MessageBuffer이 지워집니다.

다음 코드를 내 창에 추가하여이 클래스의 인스턴스를 만들고 DataContext을 설정하십시오. 내 을 MessageToSend에 바인딩하고 내 인바운드 TextBlockMessageBuffer에 바인딩하고 Button을 연결하여 SendMessage으로 전화합니다.

일단 테스트 객체에 대해 UI가 작동하게되면 같은 인터페이스를 구현하는 다른 클래스를 빌드합니다.이 인터페이스는 속성 설정자와 상호 작용하는 개인 DanMessengerClient 객체 만 생성합니다. 그렇다면 창 대신에이 객체의 인스턴스를 만들 수 있습니다.

실제의 메시징 클라이언트

아마 당신은 텍스트와 특별한 뭔가를 할 수 있도록 예를 들어, 당신이 LastMessageReceived 속성을 구현 할 수 있습니다, 더 정교해야 할 것입니다, 같은 그것은 ToolTip에 넣어. MessageBuffer 속성은 실제로 어떤 식 으로든 서식있는 텍스트를 지원해야 할 수도 있습니다. 그러나 이것은 좋은 출발점입니다.

관련 문제