Xamarin Forms ListView不显示内容

时间:2018-08-10 09:56:13

标签: listview xamarin.forms

我正在渲染此ListView

<StackLayout>
<Label Text="Test"/> //This Label is getting rendered
<ListView  ItemsSource="{Binding MusicList,Mode=TwoWay}"
                HasUnevenRows="True"
                IsPullToRefreshEnabled="True"
                CachingStrategy="RecycleElement"
                SeparatorColor="DarkGray">
      <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Label Text="{Binding Name}" TextColor="Black"/>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackLayout>

将ItemsSource绑定到ObservableCollection<Music>中可用的ViewModel。这就是我绑定ViewModel

的方式
public MainPage()
{
    BindingContext = new MainViewModel();
    InitializeComponent();
}

这是我的ViewModel,这里我调用API方法来获取数据。

    private ObservableCollection<Music> _MusicList=new ObservableCollection<Music>();
    public ObservableCollection<Music> MusicList
    {
        get { return _MusicList; }
        set
        {
            if (_MusicList != value)
            {
                _MusicList = value;
                OnPropertyChanged("_MusicList");
            }
        }
    }
    public MainViewModel()
    {
        api = new ApiHelper();
        GetSongs();
    }

    public async void GetSongs()
    {
        _MusicList = new ObservableCollection<Music>(await api.GetMusicListAsync());
    }

数据进入ObservableCollection<Music> enter image description here

更新

仅出于测试目的,我尝试绑定简单的字符串列表ListStrings = new List<string> {"A","B","C","D","E","F" };,但它也没有显示。

更新 现在,我重写onAppearing方法并初始化了我的列表,并将ListView ItemsSource设置为它。并且它现在可以工作了。但是不知道为什么它不能与绑定一起工作。

4 个答案:

答案 0 :(得分:3)

有些事情可能有问题。

  1. ItemsSource="{Binding MusicList,Mode=TwoWay}"有充分的理由使其成为TwoWay吗?如果没有,请不要这样做。
  2. BindingContext之后设置InitializeComponent();
  3. 获取数据时请勿创建新的ObservableCollection。通过创建新的集合,您将失去数据绑定。而是这样更改它:

    public async void GetSongs()
    {
        var result = await api.GetMusicListAsync();
    
        foreach (var r in result)
            _MusicList.Add(r);
    }
    

答案 1 :(得分:1)

我认为您在加错财产方面犯了错误:

import { StyleSheet, Dimensions } from 'react-native';
import Colours from '../models/Colours';

const MARGIN = 20;
const h = Dimensions.get("window").height;
const w = Dimensions.get("window").width;
const pageH = h - 65 - 50 - 5; // header, tabs, safe

const Styles = StyleSheet.create({
dark: {
    backgroundColor: Colours.DARK
},
black: {
    backgroundColor: Colours.BLACk
},
page: {
    //flex: 1,
    //flexDirection: 'row'.
    backgroundColor: Colours.DARK
},
centerContainer: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
},
fullPage: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    height: pageH
},
modalBG: {
    position: 'absolute',
    top: 0,
    left: 0,
    flex: 1,
    width: w,
    height: h,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: Colours.RGBA_BLACK
},
centerBlackMargin: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    margin: 1,
    backgroundColor: Colours.RGBA_BLACK
},

list: {
    borderColor: Colours.DARK
},
listTitle: {
    color: Colours.WHITE,
    fontSize: 16
},

listItem: {
    backgroundColor: Colours.DARK,
    borderColor: Colours.DARKER,
    borderBottomWidth: 1,
    height: 60
    //borderBottomColor: '#bbb',
    //borderTopWidth: 0,
    //borderBottomWidth: 0
    //StyleSheet.hairlineWidth,
},
listItemPress: {
    borderColor: Colours.DARKER
},

input: {
    color: Colours.GREY
    //height: 60
    //borderBottomColor: '#bbb',
    //borderTopWidth: 0,
    //borderBottomWidth: 0
    //StyleSheet.hairlineWidth,
},
textarea: {
    color: Colours.GREY,
    fontSize: 18,
    marginLeft: 14,
    marginTop: 15,
    paddingLeft: 0,
    paddingRight: 15,
    borderColor: 'transparent',
    borderBottomWidth: 1,
    borderBottomColor: Colours.DARKER
},
listItemContainer: {
    backgroundColor: Colours.DARK
},

listCols: {
    flex: 1,
    flexDirection: 'row',
    paddingLeft: 10
},

subtitle: {
    color: Colours.DARKGREY,
    backgroundColor: Colours.DARK,
    fontSize: 12
},

title: {
    color: Colours.WHITE,
    fontSize: 18
},

headerTitle: {
    fontSize: 24,
    color: Colours.WHITE
},

headerSide:{
    flex: 0,
    flexBasis: 48
},
headerBody:{
    flex: 1,
},

bigTitle: {
    fontSize: 48,
    color: Colours.WHITE
},
midTitle: {
    fontSize: 36,
    color: Colours.WHITE
},
smallTitle: {
    fontSize: 12,
    color: Colours.DARKGREY
},


checkbox: {
    marginRight: MARGIN
},
// input: {
//  width: 200,
//  height: 40,
//  fontSize: 24,
//  backgroundColor: Colours.RED
// },

sendButton: {
    marginTop: 25,
    paddingRight: 15,
    paddingLeft: 15,
},
sidePadding: {
    paddingRight: MARGIN,
    paddingLeft: MARGIN,
},
trackFooter: {
    paddingTop: MARGIN,
    paddingRight: MARGIN,
    paddingLeft: MARGIN,
},

button: {
    color: Colours.WHITE,
    fontSize: 18,
    backgroundColor: Colours.RED
},

cancelTrack: {
    color: Colours.GREY,
    textAlign: 'center',
    padding: 10
},
textWarn: {
    color: Colours.RED,
    textAlign: 'center',
    marginTop: 5
},
textCenter: {
    color: Colours.GREY,
    textAlign: 'center',
    marginTop: 10,
    //fontSize: 21
},

icon: {
    color: Colours.GREY
},

bgRed: {
    backgroundColor: Colours.RED
},
bgBlue: {
    backgroundColor: Colours.BLUE
},
bgYellow: {
    backgroundColor: Colours.YELLOW
},

dashNotEnough: {
    textAlign: 'center',
    fontSize: 21,
    color: Colours.DARKGREY
},

dashFooter: {
    height:150,
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    //backgroundColor: Colours.YELLOW
},

centeredScreen: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    //backgroundColor: Colours.YELLOW
},
centeredScreenCol: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: "center",
    alignItems: "center",
    //backgroundColor: Colours.BLUE
}


});

export default Styles;

就像@Gerald所说的那样,请听从他的建议,我想补充一下,您可以解决他提到的第三个问题。

如果每次获取数据时都创建一个Observable Collection,则会丢失数据绑定。如果您使用的foreach方法会多次引发集合更改事件,那么如果列表很大,可能对您来说是个问题。

以下扩展收集支持不同类型的收集,并具有重置可观察收集的属性。

在视图模型构造器上,您可以像这样初始化一次集合:

private ObservableCollection<Music> _MusicList=new 
ObservableCollection<Music>();
public ObservableCollection<Music> MusicList
{
    get { return _MusicList; }
    set
    {

            _MusicList = value;
            OnPropertyChanged("MusicList");  //You should raise property change on your Binding variable.

    }
}

然后,每当您从API中获取数据时,您都将执行以下操作:

public MusicPageViewModel()
{
     MusicsData=new ExtendedCollection<Music>();
}

我希望它可以帮助您实现Observable集合。这是扩展的可观察的集合,您可以使用它,并在需要时进一步扩展它:

public GetMusicsData()
{
     MusicsData.Reset(YourApi.GetMusics());
}

答案 2 :(得分:1)

今天我找到了解决方案。

    public MainPage()
    {
        InitializeComponent();
        BindingContext = this; //Added this 
    }

仅在构造函数中添加了BindingContext = this;。我不知道Xamarin到底出了什么问题。

答案 3 :(得分:0)

此问题已通过更改在观察对象中声明属性的方式解决。示例:

失败

public class MusicItem
{
     public string Name;
}

这很成功:

public class MusicItem
{
     public string Name {get; set;}
}

Binding 在第一个示例中找不到属性 Name,但在第二个示例中找到了。