Kieran Ojakangas
Kieran Ojakangas

Reputation: 535

Get window that is NOT MainWindow WPF

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

Answers (1)

Janne Matikainen
Janne Matikainen

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

Related Questions