编码入门。我的视图遇到问题,无法绑定我的UserModel类型的Observable集合。数据是通过Debug.WriteLine显示的,它不会绑定到View。这是我的代码。
视图-由ItemsSource设置的绑定。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ic="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
x:Class="Monger.View.HomePage">
<ContentPage.Content>
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Horizontal" Padding="25,0,15,10" Margin="0,10,0,0">
<StackLayout Orientation="Horizontal" Padding="10,0,5,0">
<ic:CircleImage HeightRequest="60" WidthRequest="60" Aspect="AspectFill" Source="http://placekitten.com/400/300" HorizontalOptions="Start"/>
<Label Margin="9,0,0,0" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" FontSize="30" TextColor="#A3D1F5" Text="{Binding DeviceEui}"/>
</StackLayout>
</StackLayout>
<BoxView HeightRequest="1" BackgroundColor="Black" HorizontalOptions="FillAndExpand" />
<StackLayout Padding="20,0,20,0" Margin="0,10,0,0">
<ListView x:Name="DeviceListView" SelectedItem="{Binding DeviceSelected}" ItemSelected="DeviceList_ItemSelected" ItemsSource="{Binding DevicesDisplay}" Header="Devices" SeparatorColor="#A3D1F5">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding DeviceEui}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
<StackLayout Margin="0,0,0,30" Padding="20,0,20,0">
<Button Text="Add Device" BorderRadius = "20" BackgroundColor="#A3D1F5" Command="{Binding AddDeviceCommand}"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
查看背后的代码-将慢慢摆脱这里的大部分代码,以使它们成为MVVM。目前,它只是检查权限,如果可以,则触发LoadDevicesCommand,将绑定上下文设置为HomePageViewModel并初始化新的HomePageViewModel。
namespace Monger.View
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HomePage : ContentPage
{
public HomePage ()
{
InitializeComponent ();
ViewModel = new HomePageViewModel(new PageService());
}
protected async override void OnAppearing()
{
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
{
await DisplayAlert("Need location", "We need your location to display where you are on the map.", "OK");
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
//Best practice to always check that the key exists
if (results.ContainsKey(Permission.Location))
status = results[Permission.Location];
}
if (status == PermissionStatus.Granted)
{
ViewModel.LoadDevicesCommand.Execute(this);
base.OnAppearing();
}
else if (status != PermissionStatus.Unknown)
{
await DisplayAlert("Location Denied", "Can not continue, try again.", "OK");
}
}
catch (Exception)
{ };
}
private HomePageViewModel ViewModel
{
get { return BindingContext as HomePageViewModel; }
set { BindingContext = value; }
}
private void DeviceList_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
ViewModel.DeviceSelectedCommand.Execute(e.SelectedItem);
}
}
}
视图模型-首次使用Sqlite创建表,然后在启动时获取表(如果尚不存在)。为将来设置上下文操作,但无法使绑定生效。添加设备将添加一个UserModel对象,将其插入sql数据库中,然后将其添加到UserModel类型的Observable集合中。应该已触发“属性更改”来更新绑定。
namespace Monger.ViewModel
{
class HomePageViewModel : BaseViewModel
{
private HttpClient _client = new HttpClient();
private ObservableCollection<UserModel> _devices;
private readonly IPageService _pageService;
private UserModel _deviceSelected;
public UserModel DeviceSelected { get { return _deviceSelected; } set { SetValue(ref _deviceSelected, value); } }
private List<UserModel> _userDevices;
private SQLiteAsyncConnection _connection;
public ObservableCollection<UserModel> DevicesDisplay
{
get { return _devices; }
set { SetValue(ref _devices, value); }
}
public String _deviceEui;
public ICommand DeviceSelectedCommand { get; private set; }
public ICommand AddDeviceCommand { get; private set; }
public ICommand LoadDevicesCommand { get; private set; }
public HomePageViewModel(IPageService pageService)
{
_connection = DependencyService.Get<ISQLiteDb>().GetConnection();
_pageService = pageService;
LoadDevicesCommand = new Command(GetSqlConnection);
AddDeviceCommand = new Command(AddDevice);
DeviceSelectedCommand = new Command<UserModel>(async vm => await OnDeviceSelected(vm));
}
private async void GetSqlConnection() {
await _connection.CreateTableAsync<UserModel>();
_userDevices = await _connection.Table<UserModel>().ToListAsync();
DevicesDisplay = new ObservableCollection<UserModel>(_userDevices);
}
private async Task OnDeviceSelected(UserModel Selected)
{
if (Selected == null)
return;
DeviceSelected = null;
_deviceEui = Selected.DeviceEui;
await _pageService.PushModalAsync(new MapPage(_deviceEui));
}
public async void AddDevice() {
var userdevice = new UserModel { DeviceEui = "0000000000000777", DeviceName = "Ryans Laptop", DeviceCategory = "phone.png" };
await _connection.InsertAsync(userdevice);
DevicesDisplay.Add(userdevice);
Debug.WriteLine(_devices[0].DeviceCategory);
}
}
}
BaseViewModel-来自Mosh教程的代码
namespace Monger.ViewModel
{
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(propertyName));
}
protected void SetValue<T>(ref T backingField, T Value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(backingField, Value))
return;
backingField = Value;
OnPropertyChanged(propertyName);
}
}
}
答案 0 :(得分:1)
您没有绑定Listview的ItemsSource
<ListView x:Name="DeviceListView" ItemsSource="{Binding DevicesDisplay}" SelectedItem="{Binding DeviceSelected}" ItemSelected="DeviceList_ItemSelected" Header="Devices" SeparatorColor="#A3D1F5">
答案 1 :(得分:0)
已解决:在列表视图和显示的数据上将hasUnevenRows设置为true。