1

I am trying WPF Binding. I wrote small app, but have problem, my UI not updating. Here is my code:

<Grid>
    <Button Content="Button" HorizontalAlignment="Left" Margin="345,258,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
    <TextBox x:Name="text" HorizontalAlignment="Left" Height="23" Margin="75,165,0,0" TextWrapping="Wrap" Text="{Binding Path=Count}" VerticalAlignment="Top" Width="311"/>
</Grid>

And code-behind:

namespace WpfApplication1
{   
    public partial class MainWindow : Window
    {
        MyClass mc;

        public MainWindow()
        {
            InitializeComponent();
        mc = new MyClass(this.Dispatcher);

        text.DataContext = mc;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Task task = new Task(() =>
        {
            mc.StartCounting();
        });

        task.ContinueWith((previousTask) =>
        {

        },
        TaskScheduler.FromCurrentSynchronizationContext());

        task.Start();
    }
}

public class MyClass
{
    public int Count { get; set; }
    public Dispatcher MainWindowDispatcher;

    public MyClass(Dispatcher mainWindowDispatcher)
    {
        MainWindowDispatcher = mainWindowDispatcher;
    }

    public void StartCounting()
    {
        while (Count != 3)
        {
            MainWindowDispatcher.Invoke(() =>
            {
                Count++;                    
            });
        }
    }
}

}

What is the problem. And am i wrote this correctly, is there any better ways to do this?

BJladu4
  • 263
  • 4
  • 15

1 Answers1

6

In order to support two-way WPF DataBinding, your data class must Implement the INotifyPropertyChanged interface.

First of all, Create a class that can notify property changes by marshalling them to the UI thread:

public class PropertyChangedBase:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        Application.Current.Dispatcher.BeginInvoke((Action) (() =>
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }));
    }
}

Then, have your MyClass inherit from this and raise property change notifications properly whenever the Count property is changed:

public class MyClass: PropertyChangedBase
{
    private int _count;
    public int Count
    {
        get { return _count; }
        set
        {
            _count = value;
            OnPropertyChanged("Count"); //This is important!!!!
        }
    }

    public void StartCounting()
    {
        while (Count != 3)
        {
            Count++; //No need to marshall this operation to the UI thread. Only the property change notification is required to run on the Dispatcher thread.
        }
    }
}
Federico Berasategui
  • 43,562
  • 11
  • 100
  • 154