UserBuzzer
UserBuzzer

Reputation: 51

Property is not updating in textbox - WPF

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

Answers (2)

UserBuzzer
UserBuzzer

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

Damir Arh
Damir Arh

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

Related Questions