Reputation: 151
I am creating a chatting app using WCF-Duplex and WPF. Is there is any way to call a UI function when the callback method (which is in another class than the UI) is invoked from the server?!
Here is a sample of my classes:
Service:
[ServiceContract(
Name = "GPH_QuickMessageService",
Namespace = "TextChat",
SessionMode = SessionMode.Required,
CallbackContract = typeof(IMessageServiceCallback))]
public interface IMessageServiceInbound
{
[OperationContract]
int JoinTheConversation(string userName);
} public interface IMessageServiceCallback
{
[OperationContract(IsOneWay = true)]
void NotifyUserJoinedTheConversation(string userName);
}
The JoinTheConversation invokes NotifyUserJoinedTheConversation method at the client
The Client: The Form:
public partial class Account : Window
{
public Account()
{
InitializeComponent();
}
public void updateUsersInConversation(string username)
{
TreeViewItem item = new TreeViewItem();
item.Header = username;
contactsTree.Children.Add(item);
}
}
The callback implementation at the client
[CallbackBehavior(UseSynchronizationContext = false)]
public class ChatCallBack : GPH_QuickMessageServiceCallback, IDisposable
{
public ChatCallBack()
{
//UIContext = context;
}
public void NotifyUserJoinedTheConversation(string userName)
{
MessageBox.Show("IN CLIENT");
//I want to call updateUsersInConversation in the UI class
}
}
I searched alot and found a lot of things about delegation and SendOrPostCallBack but I just couldn't link all these things together. I am sorry for the long post and hope anyone can help me with that
Upvotes: 0
Views: 5467
Reputation: 18285
You can try with Dispatcher.Invoke()
inside an Event Handler registered in your Account class.
More info here: How to update UI from another thread running in another class
[Edit] Some code example:
class ChatCallBack
{
public event EventHandler<string> UserJoinedTheConversation;
public void NotifyUserJoinedTheConversation(string username)
{
var evt = UserJoinedTheConversation;
if (evt != null)
evt(this, username);
}
//other code
}
And in you Account Class:
private ChatCallBack chatCallBack;
public Account() //class constructor
{
InitializeComponent();
chatCallBack = new ChatCallBack();
chatCallBack.UserJoinedTheConversation += (sender, username) =>
{
Dispatcher.Invoke(() => updateUsersInConversation(username));
};
}
Upvotes: 1
Reputation: 222682
You can do this,
Create a method to return the Instance of the MainWindow,
public static Account _this;
public Account()
{
InitializeComponent();
_this = this;
}
public void updateUsersInConversation(string username)
{
TreeViewItem item = new TreeViewItem();
item.Header = username;
//contactsTree.Children.Add(item);
}
public static Account GetInstance()
{
return _this;
}
And in your Client call back class, you can invoke the method like this
public void NotifyUserJoinedTheConversation(string userName)
{
Account temp = Account.GetInstance();
temp.updateUsersInConversation("test");
}
Upvotes: 1