所以我有一个在线数据库。我希望查询结果显示在列表框中。我试着使用数据绑定,但我认为我做得完全错误。
文件
[![在此输入图像描述][1]][1]
表
class ProductTable
{
public string id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public double Price { get; set; }
public string Type { get; set; }
public string Seller { get; set; }
public int Expiration { get; set; }
}
MainViewModel.cs
namespace Test
{
class MainViewModel
{
IMobileServiceTable<ProductTable> product = App.MobileService.GetTable<ProductTable>();
//In this method, load your data into Products
public async void Load()
{
// This query filters out completed TodoItems.
MobileServiceCollection<ProductTable, ProductTable> Products = await product
.Where(ProductTable => ProductTable.Price == 15)
.ToCollectionAsync();
// itemsControl is an IEnumerable that could be bound to a UI list control
IEnumerable itemsControl = Products;
}
}
}
XAML
<Page x:Name="PAGE"
xmlns:local="clr-namespace:Test;assembly=Version1">
<Grid>
<Grid.DataContext>
<local:MainViewModel />
</Grid.DataContext>
<ListBox Margin="10,10,10,100" x:Name="lb" ItemsSource="{Binding Products}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" FontSize="10"></TextBlock>
<TextBlock Text="{Binding Title}" FontSize="10"></TextBlock>
<TextBlock Text="{Binding Description}" FontSize="10"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Page>
解决方案
表需要显式声明JSON属性名称,否则将无法使用数据绑定。
表.cs
public class ProductTable
{
[JsonProperty(PropertyName = "id")]
public string id { get; set; }
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "Title")]
public string Title { get; set; }
[JsonProperty(PropertyName = "Description")]
public string Description { get; set; }
[JsonProperty(PropertyName = "Price")]
public double Price { get; set; }
[JsonProperty(PropertyName = "Type")]
public string Type { get; set; }
[JsonProperty(PropertyName = "Seller")]
public string Seller { get; set; }
[JsonProperty(PropertyName = "Expiration")]
public int Expiration { get; set; }
}
XAML.cs您不需要声明新的列表框,只需使用itemsource即可。
private async void button1_Click(object sender, RoutedEventArgs e)
{
IMobileServiceTable<ProductTable> productTest = App.MobileService.GetTable<ProductTable>();
// This query filters out completed TodoItems.
MobileServiceCollection<ProductTable, ProductTable> products = await productTest
.Where(ProductTable => ProductTable.Type == "Test")
.ToCollectionAsync();
lb.ItemsSource = products;
}
XAML
在堆栈中,永远不要使用高度"*"这将导致严重错误
<ListBox x:Name="lb" Margin="10,10,10,100" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Width="300">
<TextBlock Text="{Binding Name}" FontSize="10"></TextBlock>
<TextBlock Text="{Binding Title}" FontSize="10"></TextBlock>
<TextBlock Text="{Binding Description}" FontSize="10"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
您正在创建两个ListBoxes-一个在未显示的代码中,另一个在XAML中,它绑定到您的DataContext。
删除代码中的最后两行,并将XAML更改为:
ItemsSource="{Binding Products}"
接下来,将Products作为类(如果要使用MVVM,则为ViewModel)上的属性公开,并确保ListBox的DataContext设置为所述ViewModel/class。
我不熟悉MobileServiceCollection,所以我认为它是可绑定的。如果不是,则将Products公开为ObservableCollection(如果其中的值随时间变化)或任何其他支持的集合类型。
属性细化
创建一个类:
public class MainViewModel {
//This is a property
public ObservableCollection<ProductTable> Products { get; set; }
//In this method, load your data into Products
public void Load(){
//Products = xxx
}
}
在XAML中:
<Page [...]
xmlns:local="clr-namespace:YourNamespace;assembly=YourProjectName">
<Grid>
<Grid.DataContext>
<local:MainViewModel />
</Grid.DataContext>
<!-- ListBox goes in here somewhere, still with ItemsSource bound to Products -->
</Grid>
</Page>
请在此处阅读有关命名空间的更多信息。
通过这样做,您的Windows的DataContext将被设置为MainViewModel(也可以命名为ProductsViewModel)。由于您的ListBox将在您的Window中,它将继承(由于属性值继承)相同的DataContext。
Binding
将在ViewModel上查找属性"Products"。
您需要在某个地方调用Load()
方法。
第2部分-查看代码后
请注意,我无法运行代码,所以我的飞行有些盲目。
购买.xaml.cs
public sealed partial class Buy : Page
{
private readonly MainViewModel _viewModel;
public Buy()
{
this.InitializeComponent();
_viewModel = new MainViewModel();
DataContext = _viewModel;
}
private async void button1_Click(object sender, RoutedEventArgs e)
{
_viewModel.Load();
}
}
MainViewModel.cs
public class MainViewModel : INotifyPropertyChanged
{
IMobileServiceTable<ProductTable> product = App.MobileService.GetTable<ProductTable>();
public List<ProductTable> Products { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
public async void Load()
{
Products = await product
.Where(ProductTable => ProductTable.Price == 15)
.ToListAsync();
//Notify that the property has changed to alert to UI to update.
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Products)));
}
}
您需要将ProductTable公开,否则将出现编译错误。
希望以上内容将使您能够使用上面描述的ItemsSource绑定来绑定ListBox。
请注意,上述代码不一定是最佳实践。
后面的代码中不需要这一行
ListBox lb = new ListBox();
你可以保留
lb.ItemsSource = Products;
或者您可以将绑定到XAML 中的MobileServiceCollection
<ListBox Margin="10,10,10,100" x:Name="lb" ItemsSource="{Binding Products}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Title}"/>
<TextBlock Text="{Binding Description}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>