如何通知IEnumerable

时间:2014-01-04 19:51:29

标签: .net wpf binding ienumerable

当App.StaticLib.Search.SearchDetail被更改时,我在集合上调用NotifyPropertyChanged。

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

但这不会导致绑定到SearchFieldsListCurrent的UI元素获得新的IEnumerable
这是一个集合,但我无法弄清楚如何手动调用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"); }
}

3 个答案:

答案 0 :(得分:1)

尝试手动刷新您的用户界面

ComboBox1.Items.Refresh();

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

答案 1 :(得分:1)

好的,根据我们在问题评论中的讨论,我就是这样做的:

在绑定到gui / control的类中(我将其称为您的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"); }
}

无论如何,您不需要SearchDetail的支持字段,您已将该值存储在App.StaticLib.Search.SearchDetail中。如果您在viewmodel中使用此SearchDetail属性更改搜索详细信息(或使用您的gui反过来又应该更新此属性),它还会更新App.StaticLib.Search.SearchDetail,并触发所需的NotifyPropertyChanged()以便所有内容都应该在这种情况下工作。

对于直接在App.StaticLib.Search.SearchDetail中发生更改的情况,我建议您向App.StaticLib.Search添加一些事件,您可以在此视图模型中使用此事件。

在viewmodel的构造函数中(或者适当的),您可以订阅此事件:

App.StaticLib.Search.SearchDetailChanged += SearchDetailChangedHandler;

再次在你的viewmodel中你有它的处理程序,它看起来像这样:

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

因此,如果您直接更改App.StaticLib.Search.SearchDetail,它也会更新您的gui。
(不要忘记在App.StaticLib.Search.SearchDetail setter中提出此事件。

答案 2 :(得分:0)

DataGrid反映了 NotifyCollectionChanged 的变化。为此,使用 ObservableCollection&lt;&gt; 而不是IEnumerable&lt;&gt;。如果您不想这样做并希望仅使用List或IEnumerable进行,那么每次从属性的getter返回 List 的新实例,然后触发PropertyChanged,这有点棘手但是有效为了我 。