15

We have two textBlocks like this: (we used .NET FW 3.0)

<TextBlock Grid.Column="0" Name="tabName" Style="{StaticResource textBlockBarStyle}" HorizontalAlignment="Left">
  <TextBlock.Margin>
      <Binding Converter="{StaticResource dpiConverter}">
          <Binding.ConverterParameter>
               <Thickness Left="3" Top="6" Right="0" Bottom="0"/>
          </Binding.ConverterParameter>
      </Binding>
  </TextBlock.Margin>
</TextBlock>

and

<TextBox  x:Name="txtBoxHelp" 
          IsReadOnly="True" Style="{DynamicResource txtBoxHelpStyle}" 
          IsTabStop="False" 
          Text="some text" MouseLeftButtonDown="txtBoxHelp_MouseLeftButtonDown">
     <TextBox.Margin>
        <Binding Converter="{StaticResource dpiConverter}">
            <Binding.ConverterParameter>
                 <Thickness Left="7" Top="0" Right="0" Bottom="0"/>
            </Binding.ConverterParameter>
        </Binding>
     </TextBox.Margin>
</TextBox>

These two textBlocks work well on other OS-es, but sometimes miss on the Windows XP Home Version with SP3. We have tried many ways to refresh these, but failed.

We tried:

  1. UpdateLayout
  2. InvalidateVisual
  3. Changed the set Text property in code to binding mode.

How to force these controls to refresh?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Cooper.Wu
  • 4,335
  • 8
  • 34
  • 42

4 Answers4

21

This works for us without the need to create a new thread. It schedules the action to start when all of the bindings have updated themselves first.

           Application.Current.Dispatcher.BeginInvoke(
                DispatcherPriority.Background,
                new Action(() =>
                    {
                        // Do something here.
                    }));
Helper
  • 211
  • 2
  • 3
5

The way to make controls live update in WPF is by TwoWay databinding. So make sure all the viewModel properties you bind to are Dependency Properties or implement INotifyPropertyChanged (and handled correctly) and also that their Binding.Mode = TwoWay.

Check out Rudi Grobler's 10 things I didn't know about WPF data binding

Some databinding articles:

  1. WPF Data Binding - Part 1 By Joel Ivory Johnson alt text
  2. Moving Toward WPF Data Binding One Step at a Time By Josh Smith
Community
  • 1
  • 1
Soni Ali
  • 18,464
  • 16
  • 44
  • 53
  • I don't think this could solve the issue, because we have tried one-way binding. – Cooper.Wu May 04 '09 at 13:57
  • The whole reason for the question is that the binding does not work properly. When you change the property it should refresh but it does not because the UI thread is 'busy' – Paul McCarthy Jun 30 '22 at 15:55
4

Thread thread = new Thread(new ThreadStart(delegate()
                {
                    Thread.Sleep(200); // this is important ...
                    try
                    {
                        this.Dispatcher.BeginInvoke(DispatcherPriority.Send,
                            new NoArgsHandle(delegate()
                            {
                               // do something, set .Text = "some text"
                            }));
                    }
                    catch { }
                }));
                thread.Name = "thread-UpdateText";
                thread.Start();

It works well.

Cooper.Wu
  • 4,335
  • 8
  • 34
  • 42
0

I have been struggling with this particular issue for a long time and it seems like the suggestion made by Cooper Wu comes very close to a definitive solution, combined with the comment from Declan Taylor. It still didn't work out completely in my case, but it brought me to this piece of code:

Thread thread = new Thread(new ThreadStart(delegate ()
{
    Thread.Sleep(200); // this is important ...
    try
    {
        this.Dispatcher.BeginInvoke(DispatcherPriority.Send,
            new Action(delegate ()
            {
                DoSomething();
            }));
    }
    catch { }
}));
thread.Name = "ThreadName";
thread.Start();

The difference being that the NoArgsHandle was replace by Action, but the delegate is still there. I have tweaked a bit with the Sleep time but that will only shave off a fraction of a second. I assume the thread.Name is necessary to avoid getting multiple threads with the same name but leaving it out didn't seem to cause any problems.

Remco
  • 21
  • 3