为什么不在RaisePropertyChanged上更新UI?

时间:2013-01-04 16:53:26

标签: c# binding

我有一个静态IList,它充当静态类中的存储库:

//静态类设置

public static IList RecentSearchedRepo = new ObservableCollection<object>();

和IList位于另一个类中,我将UI网格绑定到:

//组件类

private IList recentsearch = new ObservableCollection<object>();
public IList RecentSearch
{
    get
    {
        return recentsearch;
    }
    set
    {
        recentsearch = value;
        RaisePropertyChanged("RecentSearch");
    }
}

我将对象添加到RecentSearchedRepo:

RecentSearchedRepo.add(searchitem)

然后将RecentSearch设置为静态列表

RecentSearch = Settings.RecentSearchedRepo;

XAML片段:

<GridLayout:RecentSearchGrid x:Name="recentSearchGrid" ItemsSource="{Binding RecentSearch}" />
来自RecentSearchGrid类的

片段,它扩展了UserControl:

 public IList ItemsSource
 {
     get
     {
         return GetValue(ItemsSourceProperty) as IList;
     }
     set
     {
         SetValue(ItemsSourceProperty, value);
     }
}

private static readonly DependencyProperty ItemsSourceProperty =
                    DependencyProperty.Register("ItemsSource", typeof(IList), typeof(RecentSearchGrid), new PropertyMetadata(null, OnItemsSourcePropertyChanged));


private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
     RecentSearchGrid source = d as RecentSearchGrid;

     if (source != null)
     {
      source.setListforgrid(source.ItemsSource);
     }
}

问题是,当我将第一项添加到RecentSearchedRepo时,UI已更新,但在每次后续添加时,UI都不会更新。

3 个答案:

答案 0 :(得分:1)

而不是:

RecentSearch = Settings.RecentSearchedRepo;

尝试做:

RecentSearch.Clear();
var freshData = Settings.RecentSearchedRepo;
if (freshData != null)
    foreach (var item in freshData)
        RecentSearch.Add(item);

您通过重新分配引用来终止绑定。

编辑:在您之后

你正在倒退:OnItemsSourcePropertyChanged不应该设置源,它实际上根本不应该存在。
您必须在 RecentSearchGrid.xaml 中绑定到 RecentSearchGrid.xaml.cs 中声明的ItemsSource依赖项属性

答案 1 :(得分:0)

我认为这里没有足够的信息来回答你的问题。以下简单的应用程序镜像了我在问题中描述的场景,它按预期工作:

// MySettings.cs
public static class MySettings
{
    public static IList RecentSearchedRepo = new ObservableCollection<object>();
}

// MyVm.cs
public class MyVm : INotifyPropertyChanged
{
    private IList recentSearch = new ObservableCollection<object>();

    public event PropertyChangedEventHandler PropertyChanged;

    public MyVm()
    {
        this.RecentSearch = MySettings.RecentSearchedRepo;
    }

    public IList RecentSearch
    {
        get { return recentSearch; }
        set 
        { 
            recentSearch = value;
            this.RaisePropertyChanged("RecentSearch");
        }
    }

    private void RaisePropertyChanged(string p)
    {
        if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(p));
    }
}

// MainWindow.xaml.cs
public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();

        // Initialization as described in the question
        MySettings.RecentSearchedRepo.Add("SearchItem1");
        MySettings.RecentSearchedRepo.Add("SearchItem2");

        this.DataContext = new MyVm();
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        // Add a new item later
        MySettings.RecentSearchedRepo.Add("NewlyAddedSearchItem");
    }
}

// MainWindow.xaml
<Window x:Class="ScratchWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel>
        <Button DockPanel.Dock="Bottom" Content="Add new Search Item" Click="Button_Click_1" />
        <ListBox ItemsSource="{Binding RecentSearch}" />
    </DockPanel>
</Window>

我将尝试戴上我的通灵帽并询问您是否可能在错误的收藏中添加其他物品。在添加单个项目后,是否会重新创建集合并将其放置在绑定中,但是后面的项目是否会添加到原始集合而不是新集合中?

鉴于您声明RecentSearchGrid是UserControl,我们还可以推断ItemsSource的实现可能是自定义的,而不是从ItemsControl继承的标准实现。 RecentSearchGrid可能会以某种方式错误地破坏绑定。

我同意狒狒的观点。 OnItemsSourcePropertyChanged的目的是什么?在一个典型的实现中,我不希望它存在。

答案 2 :(得分:0)

问题可能如下:  如果实例未更改,则不会调用 OnItemsSourcePropertyChanged 。 从WPF的角度来看,当您 RaisePropertyChangeEvent 时,绑定集合的实例不会更改, PropertyChange 处理程序根本不会被调用。

在应用的生命周期内,Settings.RecentSearchedRepo是同一个实例吗?