25

If my code looks somewhat like the code beneath, would it be possible to refresh all bindings directly or would I have to hard-code all the bindings to refresh?

Service-side:

[ServiceContract]
public interface IMyServiceContract {
    [OperationContract]
    MyDataContract GetData();
}
[ServiceBehavior]
public class MyService {
    [OperationBehavior]
    public MyDataContract GetData() {
        MyDataContract data = new MyDataContract();
        data.val1 = "123";
        data.val2 = "456";
        return data;
    }
}
[DataContract]
public class MyDataContract {
    [DataMember]
    public string val1;
    public string val2;
}

Client-side xaml (namespace boilerplate code omitted):

<Window x:Class="MyWindow" DataContext="{Binding RelativeSource={RelativeSource Self}}" Title="{Binding Path=val1, Mode=OneWay}">
    <DockPanel>
        <TextBlock Text="{Binding Path=val1, Mode=OneWay}"/>
        <TextBlock Text="{Binding Path=val2, Mode=OneWay}"/>
    </DockPanel>
</Window>

Client-side code-behing:

public partial class MyWindow {
    MyServiceClient client = new MyServiceClient();
    MyDataContract data;
    public string val1 {get{return data.val1;}}
    public string val2 {get{return data.val2;}}
    DispatcherTimer updateTimer = new DispatcherTimer();

    public MyWindow() {
        timer.Interval = new TimeSpan(0, 0, 10);
        timer.Tick += new EventHandler(Tick);
        Tick(this, null);
        timer.Start();
        InitializeComponent();
    }

    void Tick(object sender, EventArgs e) {
        data = client.GetData();
        // Refresh bindings
    }
}

Please disregard any coding standards violations in the example code since it is simply intended as an example for the intended use.

Teo Klestrup Röijezon
  • 5,097
  • 3
  • 29
  • 37
  • Does this answer your question? [Good way to refresh databinding on all properties of a ViewModel when Model changes](https://stackoverflow.com/questions/4651466/good-way-to-refresh-databinding-on-all-properties-of-a-viewmodel-when-model-chan) – StayOnTarget Apr 04 '23 at 18:15

3 Answers3

38

Found the answer, seems like that calling PropertyChanged with the PropertyChangedEventArgs property name set to "" refreshes all bindings.
The DataContext changing worked too, although this felt a bit "cleaner".

Teo Klestrup Röijezon
  • 5,097
  • 3
  • 29
  • 37
  • `PropertyChanged` on what exactly...the main page, the control? – ΩmegaMan Oct 02 '19 at 15:12
  • @ΩmegaMan This was ~the last time I used WPF, but if I remember correctly.. the window/main page. – Teo Klestrup Röijezon Oct 02 '19 at 16:22
  • I have a custom control on a page, and there is no direct `PropertyChanged` method on either it or the main page. I ended up doing the `DataContext=null`. – ΩmegaMan Oct 02 '19 at 16:24
  • @ΩmegaMan none of the controls are going to implement INotifyPropertyChanged; that interface would be used by the object which the controls are bound TO. – StayOnTarget Oct 31 '22 at 19:23
  • This is documented: https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifypropertychanged.propertychanged?redirectedfrom=MSDN&view=net-7.0#remarks and mentioned here: https://stackoverflow.com/a/4651672/3195477. Although in my experience only `""` works, `null` does not despite the documentation. – StayOnTarget Apr 04 '23 at 18:16
  • Invoking `PropertyChanged` event on a bound view model implementing `INotifyPropertyChanged` with an empty string as the property name. MVVM stuff. – Jordan May 26 '23 at 16:23
28

You can null then re-set the DataContext of the parent object.

DataContext = null;
DataContext = data;
BenCr
  • 5,991
  • 5
  • 44
  • 68
  • 2
    I seem to remember it not working, no. I think it realises that you've set it to the same reference and therfore does not rebind. – BenCr Mar 01 '11 at 18:07
  • I think this is why BenCr suggested to first "null then re-set" meaning null as a verb to set the DataContext to null and then set back to the original DataContext so that it sees it as a change. – jpierson Jun 01 '13 at 01:59
  • That is indeed what I'm suggesting. – BenCr Jun 03 '13 at 09:05
  • I have a scenario where setting the DataContext to null will not reset the UI - it leaves the stale values in place. Only after I set the DataContext to a new value do the UI elements update. For example, I have a Master/Detail pattern and I delete the final item in the Master list. Afterwards, the Detail fields stay populated with the item info from the last item deleted. It works fine when I delete all but the last item, because I re-assign the DataContext to one of the remaining items in the Master list. Any thoughts on how to get the UI to "clear" the values when I delete the last item? – Bill Jun 12 '13 at 17:42
  • 1
    I need to withdraw my previous comments. The failure of the UI to update was due to an exception being thrown bu another line of code under the described scenario. Setting the DataContext to null when deleting the final Master item does in fact result in the Details pane "clearing" all values in the UI. – Bill Jun 12 '13 at 19:44
0

How about making "data" a dependency property. Binding your DataContext to that will make your bindings update when you re-assign "data".

Holstebroe
  • 4,993
  • 4
  • 29
  • 45