Reputation: 51
I have an issue with binding the property Message to the view. Callback returns a result from a WCF Service. I'm trying to assign this result to the property Message. My text box is never updated with new value - it always displays TEST.
public class CallbackHandler : IDataExchangeCallback, INotifyPropertyChanged
{
public CallbackHandler()
{
this.Message = "TEST";
}
public void Result(string result)
{
Message = result;
}
private string _message;
public string Message
{
get { return _message; }
set
{
_message = value;
OnPropertyChanged("Message");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
<Window x:Class="guiClient.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tb="http://www.hardcodet.net/taskbar"
xmlns:local="clr-namespace:guiClient"
Title="DataExchangeClient" Height="76" Width="297" WindowStyle="SingleBorderWindow" MinHeight="50" MinWidth="50" MaxWidth="300">
<Window.DataContext>
<local:CallbackHandler/>
</Window.DataContext>
<Grid>
<TextBox HorizontalAlignment="Left" Height="45" TextWrapping="Wrap" VerticalAlignment="Top" Width="289" Text="{Binding Path=Message}"/>
</Grid>
</Window>
HERE IS INTERFACE:
------From UserBuzzer
Callback is defined like this :
IDataExchangeCallback Callback
{
get
{
return OperationContext.Current.GetCallbackChannel<IDataExchangeCallback>();
}
}
And interface:
// The callback interface is used to send messages from service back to client.
// The Result operation will return the current result after each operation.
public interface IDataExchangeCallback
{
[OperationContract(IsOneWay = true)]
void Result(string result);
}
Upvotes: 2
Views: 847
Reputation: 51
I found solution. It's very bad, but atm i don't know how to raise event on UI thread.
namespace guiClient
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, IDataExchangeCallback
{
public MainWindow()
{
InitializeComponent();
Register();
}
public void Result(string result)
{
//this will not cause the application to hang
Application.Current.Dispatcher.BeginInvoke(new Action(
() => textBox.Text = result));
}
public void Register()
{
InstanceContext instanceContext = new InstanceContext(this);
DataExchangeClient client = new DataExchangeClient(instanceContext);
client.RegisterClient(Guid.NewGuid().ToString());
}
}
}
As Damir Arh mention i used dispather. In this case i named control and passed result to Text property.
Notice also MainWindow now inherits from IDataExchangeCallback. This is also tricky: InstanceContext instanceContext = new InstanceContext(this);
If anyone know how to implement this in MVVM patern give me a call.
Upvotes: 1
Reputation: 17855
The reason could be that you're not raising PropertyChanged
on the UI thread, since you're calling it from a callback. Try using Dispatcher
to make sure the event is raised on UI thread:
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
Application.Current.Dispatcher.Invoke(() =>
handler(this, new PropertyChangedEventArgs(propertyName)));
}
}
Upvotes: 2