Question

When App.StaticLib.Search.SearchDetail is changed I call NotifyPropertyChanged on the collection.

public enumSearchDetail SearchDetail
{
    get { return searchDetail; }
    set
    {
        if (searchDetail == value) return;
        searchDetail = value;
        NotifyPropertyChanged("SearchDetail");
        NotifyPropertyChanged("SearchFieldsListCurrent");                    
    }
}

But that does not cause UI elements bound to SearchFieldsListCurrent to get a fresh IEnumerable
It is a Collection but I can't figure out how to manually call a NotifyCollectionChanged

public IEnumerable<FieldDef> SearchFieldsListCurrent
{
    get
    {
        if (App.StaticLib.Search.SearchDetail == enumSearchDetail.Basic) return SearchFieldsListBasic;
        if (App.StaticLib.Search.SearchDetail == enumSearchDetail.Advanced) return SearchFieldsListAdvanced;
        else return SearchFieldsList;
    }
    set { NotifyPropertyChanged("SearchFieldsListCurrent"); }
}
Was it helpful?

Solution

try to refresh your UI manually

ComboBox1.Items.Refresh();

or

ComboBox1.ItemsSource=null;
ComboBox1.ItemsSource=SearchFieldsListCurrent;

OTHER TIPS

Ok, based on our discussion in the question comments, this is how I would do it:

In the class that you bind to your gui/control (I will call it your viewmodel):

public enumSearchDetail SearchDetail
{
    get { return App.StaticLib.Search.SearchDetail; }
    set
    {
        if (App.StaticLib.Search.SearchDetail == value) return;
        App.StaticLib.Search.SearchDetail = value;

        // note that you can comment out these 2 lines if you use the event I describe at the end of this answer
        // since these 2 NotifyPropertyChanged would be called immediately when value is set to "App.StaticLib.Search.SearchDetail"
        NotifyPropertyChanged("SearchDetail");
        NotifyPropertyChanged("SearchFieldsListCurrent");                    
    }
}

public IEnumerable<FieldDef> SearchFieldsListCurrent
{
    get
    {
        if (SearchDetail == enumSearchDetail.Basic) return SearchFieldsListBasic;
        if (SearchDetail == enumSearchDetail.Advanced) return SearchFieldsListAdvanced;
        else return SearchFieldsList;
    }

    // I don't know the rest of your code, but I don't get what possible use could this setter have,
    // it sets no value and does nothing except trigger NotifyPropertyChanged("SearchFieldsListCurrent")
    // when you execute "SearchFieldsListCurrent = <some_value>;"
    // if you want to trigger that you can and should always do so directly, not like described above
    // set { NotifyPropertyChanged("SearchFieldsListCurrent"); }
}

Anyway, you don't need the backing field for SearchDetail, you already store that value in App.StaticLib.Search.SearchDetail. If you change search detail using this SearchDetail property in the viewmodel (or using your gui which in turn should again update this property), it will also update App.StaticLib.Search.SearchDetail, and trigger required NotifyPropertyChanged() so everything should work in this situation.

For the situation where change occurs directly in App.StaticLib.Search.SearchDetail, I suggest adding some event to App.StaticLib.Search which you would use from your viewmodel like this.

In the constructor of your viewmodel (or whereever is appropriate) you can subscribe to this event:

App.StaticLib.Search.SearchDetailChanged += SearchDetailChangedHandler;

And again in your viewmodel you have the handler for it which would look something like this:

private void SearchDetailChangedHandler()
{
    NotifyPropertyChanged("SearchDetail");
    NotifyPropertyChanged("SearchFieldsListCurrent");  
}

So if you change App.StaticLib.Search.SearchDetail directly, it will also update your gui.
(Don't forget to raise this event inside App.StaticLib.Search.SearchDetail setter).

DataGrid reflects changes on NotifyCollectionChanged. For that use ObservableCollection<> instead of IEnumerable<>. If you dont want to do that and want it to be done only with List or IEnumerable then return new instance of List every time from the getter of property and then fire PropertyChanged, this is kind of tricky but worked for me .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top