Reputation: 535
I want to call the method from the codebehind of a window that is NOT the MainWindow in my WPF application, casting the window type as I do it.
ClientCallBack.cs:
using ChattingInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace ChatClient
{
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class ClientCallback : IClient
{
public void GetMessage(string message, string userName)
{
//get casted instance of chat client window (NOT MainWindow!)
}
}
}
ChatWPFClient.xaml.cs:
using ChattingInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace ChatClient
{
/// <summary>
/// Interaction logic for ChatWPFClient.xaml
/// </summary>
public partial class ChatWPFClient : Window
{
public static IChattingService Server;
private static DuplexChannelFactory<IChattingService> _channelFactory;
public ChatWPFClient()
{
InitializeComponent();
_channelFactory = new DuplexChannelFactory<IChattingService>(new ClientCallback(), "ChattingServiceEndpoint");
Server = _channelFactory.CreateChannel();
}
private void sendMessage(object sender, RoutedEventArgs e)
{
MessageBox.Show("Not available yet!");
}
public void TakeMessage(string message, string userName)
{
chatBox.Text += userName + ": " + message + "\n";
}
}
}
How can I call the TakeMessage of this method in the other class so I can use that codebehind window to populate the XAML file for ChatWPFClient.xaml? Thanks in advance!
Upvotes: 0
Views: 322
Reputation: 5121
First create an interface that you can pass to the ClientCallback
public interface IMessageHandler
{
void TakeMessage(string message, string userName);
}
Then in the ClientCallBack take the interface as a parameter in the constructor.
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class ClientCallback : IClient
{
private IMessageHandler messageHandler;
public ClientCallBack(IMessageHandler messageHandler)
{
this.messageHandler = messageHandler;
}
public void GetMessage(string message, string userName)
{
messageHandler.TakeMessage(message, userName);
}
}
Use the interface for the ChatWpfClient and pass the instance in the constructor.
public partial class ChatWPFClient : Window, IMessageHandler
{
...
public ChatWPFClient()
{
InitializeComponent();
_channelFactory = new DuplexChannelFactory<IChattingService>(new ClientCallback(this), "ChattingServiceEndpoint");
Server = _channelFactory.CreateChannel();
}
...
// This is a part of the interface now and needs to be implemented here
public void TakeMessage(string message, string userName)
{
chatBox.Text += userName + ": " + message + "\n";
}
}
Also you could just implement the IClient on your ChatWPFClient class and decorate with the CallBackBehavior attribute and just pass itself as the callback. But don't think this is recommended, seems weird.
_channelFactory = new DuplexChannelFactory<IChattingService>(this, "ChattingServiceEndpoint");
Upvotes: 1