Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. INotifyPropertyChanged binding label problem during update in function

INotifyPropertyChanged binding label problem during update in function

Scheduled Pinned Locked Moved C#
wpfquestioncsswcfdesign
8 Posts 2 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    massisoda
    wrote on last edited by
    #1

    Hello I have a problem with update of binding of a label. I have this simple class:

    public partial class frTest : INotifyPropertyChanged
    {
    private string _message;
    public string Message
    {
    private set
    {
    _message = value;
    OnPropertyChanged("Message");
    }
    get
    {
    return _message;
    }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void OnPropertyChanged(string propertyName = null)
    {
      PropertyChangedEventHandler handler = PropertyChanged;
      if (handler != null)
      {
        handler(this, new PropertyChangedEventArgs(propertyName));
      }
    }
    
    public frTest()
    {
      InitializeComponent();
      DataContext = this;
    }
    
    private void WindowLoaded(object sender, RoutedEventArgs e)
    {
      Message = "test";
      txtDevQty.Text = "1000";
      txtDevQty.TextAlignment = TextAlignment.Center;
      txtDevQty.IsEnabled = false;
    }
    
    private void BtnNextClick(object sender, RoutedEventArgs e)
    {
      for (int i = 0; i < 1000; i++)
      {
        Message = string.Format("Tested {0} of {1}", i, 1000);
        Thread.Sleep(10);
      }
    }
    

    }

    I have in the xaml code a label with content binded to Message value

    <Label Name="lblHint" Content="{Binding Message}" HorizontalAlignment="Center" FontFamily="verdana" FontSize="11" FontWeight="Bold" Foreground="Black" Grid.ColumnSpan="2"></Label>

    The problem is that when i launch the BtnNextClick function,i see the label updated only at the end of procedure,and what i would like is to see updated in every cycle the content of the label.... How can I do? I think it's a problem between my form and the ui thread? Thanks in advance Best regards

    P 1 Reply Last reply
    0
    • M massisoda

      Hello I have a problem with update of binding of a label. I have this simple class:

      public partial class frTest : INotifyPropertyChanged
      {
      private string _message;
      public string Message
      {
      private set
      {
      _message = value;
      OnPropertyChanged("Message");
      }
      get
      {
      return _message;
      }
      }

      public event PropertyChangedEventHandler PropertyChanged;
      
      protected virtual void OnPropertyChanged(string propertyName = null)
      {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
          handler(this, new PropertyChangedEventArgs(propertyName));
        }
      }
      
      public frTest()
      {
        InitializeComponent();
        DataContext = this;
      }
      
      private void WindowLoaded(object sender, RoutedEventArgs e)
      {
        Message = "test";
        txtDevQty.Text = "1000";
        txtDevQty.TextAlignment = TextAlignment.Center;
        txtDevQty.IsEnabled = false;
      }
      
      private void BtnNextClick(object sender, RoutedEventArgs e)
      {
        for (int i = 0; i < 1000; i++)
        {
          Message = string.Format("Tested {0} of {1}", i, 1000);
          Thread.Sleep(10);
        }
      }
      

      }

      I have in the xaml code a label with content binded to Message value

      <Label Name="lblHint" Content="{Binding Message}" HorizontalAlignment="Center" FontFamily="verdana" FontSize="11" FontWeight="Bold" Foreground="Black" Grid.ColumnSpan="2"></Label>

      The problem is that when i launch the BtnNextClick function,i see the label updated only at the end of procedure,and what i would like is to see updated in every cycle the content of the label.... How can I do? I think it's a problem between my form and the ui thread? Thanks in advance Best regards

      P Offline
      P Offline
      Pete OHanlon
      wrote on last edited by
      #2

      The reason you're not seeing anything is because your Thread.Sleeps are locking the UI thread. If you want to see the labels, simply wrap the loop up like this:

      Task.Factory.StartNew(() =>
      {
      for (int i = 0; i < 1000; i++)
      {
      Message = string.Format("Tested {0} of {1}", i, 1000);
      Thread.Sleep(10);
      }
      });

      M 1 Reply Last reply
      0
      • P Pete OHanlon

        The reason you're not seeing anything is because your Thread.Sleeps are locking the UI thread. If you want to see the labels, simply wrap the loop up like this:

        Task.Factory.StartNew(() =>
        {
        for (int i = 0; i < 1000; i++)
        {
        Message = string.Format("Tested {0} of {1}", i, 1000);
        Thread.Sleep(10);
        }
        });

        M Offline
        M Offline
        massisoda
        wrote on last edited by
        #3

        The sleep is necessary?

        P 1 Reply Last reply
        0
        • M massisoda

          The sleep is necessary?

          P Offline
          P Offline
          Pete OHanlon
          wrote on last edited by
          #4

          Only if you want to pause your thread long enough to actually see the update. If you remove it, you'll flood the UI with notifications.

          M 1 Reply Last reply
          0
          • P Pete OHanlon

            Only if you want to pause your thread long enough to actually see the update. If you remove it, you'll flood the UI with notifications.

            M Offline
            M Offline
            massisoda
            wrote on last edited by
            #5

            I have tried but unfortunately using task don't solve my problem... Because my code is a little bit different of what i wrote... With this code the update of the label start only when all the iterations of the for (for (int j = 0; j < 10; j++)) are completed

            public partial class frTest : INotifyPropertyChanged
            {
            private string _message;
            public string Message
            {
            private set
            {
            _message = value;
            OnPropertyChanged("Message");
            }
            get
            {
            return _message;
            }
            }

            public event PropertyChangedEventHandler PropertyChanged;
            
            protected virtual void OnPropertyChanged(string propertyName = null)
            {
              PropertyChangedEventHandler handler = PropertyChanged;
              if (handler != null)
              {
                handler(this, new PropertyChangedEventArgs(propertyName));
              }
            }
            
            public frTest()
            {
              InitializeComponent();
              DataContext = this;
            }
            
            private void WindowLoaded(object sender, RoutedEventArgs e)
            {
              Message = "test";
              txtDevQty.Text = "1000";
              txtDevQty.TextAlignment = TextAlignment.Center;
              txtDevQty.IsEnabled = false;
            }
            
            public void DoSomething()
            {
              var a = 0;
            
              for (int i = 0; i < 2000000; i++)
              {
                a++;
              }
            }    
            
            private void BtnNextClick(object sender, RoutedEventArgs e)
            {
                for (int j = 0; j < 10; j++)
                {
                  DoSomething();
            
                  Task.Factory.StartNew(() =>
                  {
            
                    try
                    {
                      for (int i = 0; i < 1000; i++)
                      {
                        Message = string.Format("Tested {0} of {1}", i, 1000);
                        Thread.Sleep(10);
                      }
                    }
                    catch (Exception ex)
                    {
            
                    }
                  });
                }
            }
            

            }

            P 1 Reply Last reply
            0
            • M massisoda

              I have tried but unfortunately using task don't solve my problem... Because my code is a little bit different of what i wrote... With this code the update of the label start only when all the iterations of the for (for (int j = 0; j < 10; j++)) are completed

              public partial class frTest : INotifyPropertyChanged
              {
              private string _message;
              public string Message
              {
              private set
              {
              _message = value;
              OnPropertyChanged("Message");
              }
              get
              {
              return _message;
              }
              }

              public event PropertyChangedEventHandler PropertyChanged;
              
              protected virtual void OnPropertyChanged(string propertyName = null)
              {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                  handler(this, new PropertyChangedEventArgs(propertyName));
                }
              }
              
              public frTest()
              {
                InitializeComponent();
                DataContext = this;
              }
              
              private void WindowLoaded(object sender, RoutedEventArgs e)
              {
                Message = "test";
                txtDevQty.Text = "1000";
                txtDevQty.TextAlignment = TextAlignment.Center;
                txtDevQty.IsEnabled = false;
              }
              
              public void DoSomething()
              {
                var a = 0;
              
                for (int i = 0; i < 2000000; i++)
                {
                  a++;
                }
              }    
              
              private void BtnNextClick(object sender, RoutedEventArgs e)
              {
                  for (int j = 0; j < 10; j++)
                  {
                    DoSomething();
              
                    Task.Factory.StartNew(() =>
                    {
              
                      try
                      {
                        for (int i = 0; i < 1000; i++)
                        {
                          Message = string.Format("Tested {0} of {1}", i, 1000);
                          Thread.Sleep(10);
                        }
                      }
                      catch (Exception ex)
                      {
              
                      }
                    });
                  }
              }
              

              }

              P Offline
              P Offline
              Pete OHanlon
              wrote on last edited by
              #6

              And what else would you expect it to do? You aren't actually starting to update Message until you have completed the other loop. Just drop your outer loop into the task factory.

              M 1 Reply Last reply
              0
              • P Pete OHanlon

                And what else would you expect it to do? You aren't actually starting to update Message until you have completed the other loop. Just drop your outer loop into the task factory.

                M Offline
                M Offline
                massisoda
                wrote on last edited by
                #7

                I cannot do it because in reality my DoSomething function do some work and start a thread that do some long operations. For this reason i need to update the label for have a feedback of where is my routine arrived

                P 1 Reply Last reply
                0
                • M massisoda

                  I cannot do it because in reality my DoSomething function do some work and start a thread that do some long operations. For this reason i need to update the label for have a feedback of where is my routine arrived

                  P Offline
                  P Offline
                  Pete OHanlon
                  wrote on last edited by
                  #8

                  Look, I cannot read your mind about what you are trying to do. You cannot keep drip feeding things through. It's simple enough, you need to update your label text from a none UI thread, so you can simply spawn that off in its own TaskFactory. In your example, you aren't starting off the update of the label until you have completed DoSomething. Step away from the keyboard right now, and actually design the interactions you need rather than throwing things on here that don't actually match what you're trying to do.

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups