我的PropertyChanged事件没有更新我在xamarin中的列表视图。 有人可以帮我吗?
当搜索栏文本更改时,将触发方法RefreshListView。
我的视图模型:
public class LebensmittelViewModel : INotifyPropertyChanged
{
private ObservableCollection<Lebensmittel> lebensmittelList = new ObservableCollection<Lebensmittel>();
public List<Lebensmittel> normalLebensmittelList = new List<Lebensmittel>();
public event PropertyChangedEventHandler PropertyChanged;
public LebensmittelViewModel()
{
normalLebensmittelList = App.LebensmittelDatabase.getAllLebensmittel();
}
public void RefreshListView(string searchBarText)
{
LebensmittelList = addItemInCollection(searchBarText);
}
public ObservableCollection<Lebensmittel> addItemInCollection(string searchBarText)
{
if (searchBarText != null)
{
foreach (var item in normalLebensmittelList)
{
if (item.Name.Contains(searchBarText) || item.Name.Contains(searchBarText.First().ToString().ToUpper()))
{
LebensmittelList.Add(item);
};
}
}
return LebensmittelList;
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ObservableCollection<Lebensmittel> LebensmittelList
{
get
{
return lebensmittelList;
}
set
{
lebensmittelList = value;
OnPropertyChanged("LebensmittelList");
}
}
}
Einkaufsliste.xaml
<ContentPage.Content>
<StackLayout Spacing="10" Padding="10">
<SearchBar x:Name="searchBar" Text="{Binding searchBarText}" Placeholder="Lebensmittel suchen..." VerticalOptions="StartAndExpand">
<SearchBar.Behaviors>
<behavior:TextChangedBehavior/>
</SearchBar.Behaviors>
</SearchBar>
<ListView x:Name="listView" ItemsSource="{Binding LebensmittelList}" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand" Orientation="Horizontal" Padding="10">
<Label Text="{Binding Name}" YAlign="Center" Font="Large"/>
<ia:Checkbox HorizontalOptions="EndAndExpand"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
Einkaufsliste.xaml.cs
public Einkaufsliste ()
{
InitializeComponent ();
BindingContext = new LebensmittelViewModel();
}
我认为一切都应该没问题,但是没有用。 希望有人可以帮助我,
谢谢
编辑汤姆:
public void RefreshListView(string searchBarText)
{
addItemInCollection(searchBarText);
}
public void addItemInCollection(string searchBarText)
{
if (searchBarText != null)
{
foreach (var item in normalLebensmittelList)
{
if (item.Name.Contains(searchBarText) || item.Name.Contains(searchBarText.First().ToString().ToUpper()))
{
AddItemToList(item);
};
}
}
}
private void AddItemToList(Lebensmittel item)
{
lebensmittelList.Add(item);
LebensmittelList = lebensmittelList;
}
答案 0 :(得分:0)
您可以尝试替换以下方法吗?
public void RefreshListView(string searchBarText)
{
LebensmittelList.Clear();
addItemInCollection(searchBarText);
}
由于您已经在使用Observable Collection,因此不需要替换该Collection。您可以添加,它将被自动观察并绑定。让我知道它是否有效!
答案 1 :(得分:0)
您似乎在LebensmittelList
方面还有很多工作。尝试执行以下操作:
public void RefreshListView(string searchBarText)
{
// this can be list clearing, if you need it
addItemInCollection(searchBarText);
OnPropertyChanged("LebensmittelList");
}
public void addItemInCollection(string searchBarText)
{
if (searchBarText != null)
{
foreach (var item in normalLebensmittelList)
{
if (item.Name.Contains(searchBarText) || item.Name.Contains(searchBarText.First().ToString().ToUpper()))
{
LebensmittelList.Add(item);
};
}
}
}
编辑: 我不知道是否有人可以称这种解决方案为优雅,但它应该可以工作。
internal class MyCollection<T> : ObservableCollection<T>
{
public void DoCollectionChanged()
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
... MyCollection<LebensmittelItem> LebensmittelList; // field and property declaration should be changed
public void RefreshListView(string searchBarText)
{
// this can be list clearing, if you need it
addItemInCollection(searchBarText);
LebensmittelList.DoCollectionChanged();
}
答案 2 :(得分:0)
执行OnPropertyChanged
时是否会调用属性set
中的RefreshListView
?
答案 3 :(得分:0)
在addItemToCollection
方法中,您正在调用以下行:
LebensmittelList.Add(item);
在这种情况下,LebensmittelList
是属性,而不是变量。第LebensmittelList.Add(item);
行有效地执行了以下操作:
var temporaryList = LebensmittelList; // Gets lebensmittelList and assigns to temporaryList
temporaryList.Add(item); // You add the item to the *variable temporaryList*
本质上,您要添加到{strong>实例 lebensmittelList
(临时副本),而不是lebensmittelList
变量。将该项添加到临时列表后,整个列表(临时列表)将被丢弃而无需“保存更改”。
要实际更新LebensmittelList
,最好调用以下方法:
private void AddItemToList(object item)
{
lebensmittelList.Add(item);
LebensmittelList = lebensmittelList;
}
答案 4 :(得分:0)
它如何实现行为TextChangedBehavior
?您是否将BindingContext
转换为LebensmittelViewModel
才能调用RefreshListView
?
我将摆脱行为:/并添加一个TextChanged
事件,创建属性SearchBarText
,因为我看不到它的声明位置,并且您将其绑定到{{ 1}},重构SearchBar
方法...,我认为它应该起作用...:)
Einkaufsliste.xaml.cs
RefreshListView
Einkaufsliste.xaml
private LebensmittelViewModel vm = new LebensmittelViewModel();
public Einkaufsliste ()
{
InitializeComponent ();
BindingContext = vm;
}
public void OnSeachBarTextChange(object e, TextChangedEventArgs args)
{
vm.RefreshListView();
}
Viewmodel
<ContentPage.Content>
<StackLayout Spacing="10" Padding="10">
<SearchBar x:Name="searchBar" Text="{Binding SearchBarText, Mode=TwoWay}" Placeholder="Lebensmittel suchen..." VerticalOptions="StartAndExpand" TextChanged="OnSeachBarTextChange">
</SearchBar>
<ListView x:Name="listView" ItemsSource="{Binding LebensmittelList}" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand" Orientation="Horizontal" Padding="10">
<Label Text="{Binding Name}" YAlign="Center" Font="Large"/>
<ia:Checkbox HorizontalOptions="EndAndExpand"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>