Xamarin表单未更新ListView

时间:2018-11-20 16:57:12

标签: c# listview xamarin xamarin.forms

我的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;
    }

5 个答案:

答案 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>