C# CollectionView、数据绑定、MVVM
大家好, 我试图在我的应用程序中实现MVVM,但无法加载数据。 我有一个主页,它工作得很好,但一旦我想导航到我的广告的详细信息,然后详细信息页面是空白的。有我的控件,所以我知道页面被加载了,只是我的数据丢失了。我似乎不知道我在哪里犯了错误。我对编码还不熟悉,所以有时我会犯一些愚蠢的错误。在过去的几个小时里,我一直在努力解决这个问题,否则我不会把它贴在这里。谢谢你的意见C# CollectionView、数据绑定、MVVM,c#,xamarin,C#,Xamarin,大家好, 我试图在我的应用程序中实现MVVM,但无法加载数据。 我有一个主页,它工作得很好,但一旦我想导航到我的广告的详细信息,然后详细信息页面是空白的。有我的控件,所以我知道页面被加载了,只是我的数据丢失了。我似乎不知道我在哪里犯了错误。我对编码还不熟悉,所以有时我会犯一些愚蠢的错误。在过去的几个小时里,我一直在努力解决这个问题,否则我不会把它贴在这里。谢谢你的意见 My HomePage <Grid Grid.Row="1" Margin="0,25,0,0">
My HomePage
<Grid Grid.Row="1" Margin="0,25,0,0">
<CollectionView x:Name="ads"
ItemsSource="{Binding AdLogEntries}"
ItemTemplate="{StaticResource HomePageTemplate}"
SelectionMode="Single"
SelectedItem="{Binding SelectedAd, Mode=TwoWay}"
SelectionChanged="CollectionView_SelectionChanged"
Margin="12,0">
</CollectionView>
</Grid>
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
BindingContext = new HomePage ViewModel();
}
async void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedAd = (AdLogEntry)e.CurrentSelection.FirstOrDefault();
if (selectedAd != null)
{
await Navigation.PushAsync(new AdDetail(selectedAd));
}
}
}
namespace Baltazar.ViewModel
{
public class HomePageViewModel : BaseViewModel
{
ObservableCollection<AdLogEntry> _adLogEntries;
public ObservableCollection<AdLogEntry> AdLogEntries { get => _adLogEntries; set { _adLogEntries = value; OnPropertyChanged(); } }
public AdLogEntry selectedAd;
public HomePageViewModel()
{
AdLogEntries = new ObservableCollection<AdLogEntry>()
{
new AdLogEntry (){Id = 0, Image = "cat.jpg", Name = "Kocka" , Description = "seda kocka na prodej, mayliva, hrava, spolecenska " ,Price = 120, },
new AdLogEntry (){Id = 1, Image = "cat2.jpg", Name = "Kocka", Description = "seda kocka na prodej, mayliva, hrava, spolecenska " ,Price = 120, },
new AdLogEntry (){Id = 2, Image = "bobtailjpg.jpg", Name = "Kocka",Description = "seda kocka na prodej, mayliva, hrava, spolecenska ", Price = 120, },
};
}
}
}
//Detail
public class AdDetailViewModel : BaseViewModel
{
AdLogEntry _adDetail;
public AdLogEntry AdDetail { get => _adDetail;set { _adDetail = value;OnPropertyChanged(); } }
public AdDetailViewModel(AdLogEntry adDetail)
{
AdDetail = adDetail;
}
}
public partial class AdDetail : ContentPage
{
//private AdLogEntry selectedAd;
public AdDetail(AdLogEntry adDetail)
{
InitializeComponent();
BindingContext = new AdDetailViewModel(adDetail);
}
}
//BaseViewModel
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected BaseViewModel()
{
}
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我的主页
公共部分类主页:ContentPage
{
公共网页()
{
初始化组件();
BindingContext=新主页视图模型();
}
异步void CollectionView\u SelectionChanged(对象发送方,SelectionChangedEventArgs e)
{
var selectedAd=(AdLogEntry)e.CurrentSelection.FirstOrDefault();
如果(selectedAd!=null)
{
等待Navigation.PushAsync(新的AdDetail(selectedAd));
}
}
}
命名空间Baltazar.ViewModel
{
公共类HomePageViewModel:BaseViewModel
{
可观察的采集记录;
公共ObservableCollection AdLogEntries{get=>\u AdLogEntries;set{{u AdLogEntries=value;OnPropertyChanged();}
选择的公共广告条目d;
公共主页视图模型()
{
AdLogEntries=新的ObservableCollection()
{
新的AdLogEntry(){Id=0,Image=“cat.jpg”,Name=“Kocka”,Description=“seda Kocka na prodej,mayliva,hrava,spolekenska”,Price=120,},
新的AdLogEntry(){Id=1,Image=“cat2.jpg”,Name=“Kocka”,Description=“seda Kocka na prodej,mayliva,hrava,spolekenska”,Price=120,},
新的AdLogEntry(){Id=2,Image=“bobtailjpg.jpg”,Name=“Kocka”,Description=“seda Kocka na prodej,mayliva,hrava,spolekenska”,Price=120,},
};
}
}
}
//细部
公共类AdDetailViewModel:BaseViewModel
{
AdLogEntry _addtail;
public AdLogEntry AdDetail{get=>_AdDetail;set{_AdDetail=value;OnPropertyChanged();}
公共AdDetailViewModel(AdLogEntry adDetail)
{
AdDetail=AdDetail;
}
}
公共部分类AddDetail:ContentPage
{
//选择的专用AdLogEntry ADD;
公共AdDetail(AdLogEntry AdDetail)
{
初始化组件();
BindingContext=新的AdDetailViewModel(adDetail);
}
}
//BaseViewModel
公共类BaseViewModel:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的BaseViewModel()
{
}
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
您的
BindingContext
是AdDetailViewModel
BindingContext = new AdDetailViewModel(adDetail);
您的绑定路径如下所示
<Label Grid.Row="3" Text="{Binding AdLogEntries.Description}"
问题出在您的详细信息页面XAML中。确切地说,问题出在XAML绑定表达式中。详细信息页面中的所有绑定都设置了错误的路径。例如,对于图像控件,它应该是
Source=“{Binding addeail.image}”
,而不是Source=“{Binding AdLogEntries.image}”
。这种情况经常发生,在调试应用程序时,您会在输出日志中捕获此类错误。您选择的编辑项不会更改,因为您没有触发PropertyChange。可以按如下方式更改视图模型逻辑:
private AdLogEntry selectedAd;
public AdLogEntry SelectedAd { get => selectedAd; set { selectedAd = value; OnPropertyChanged("SelectedAd"); } }
public ICommand AdSelectionChangedCommand => new Command(AdSelectionChanged);
private void AdSelectionChanged()
{
OnPropertyChanged("SelectedAd");
Application.Current.MainPage.Navigation.PushModalAsync(new DetailPage(SelectedAd));
}
在您的XAML中:
<CollectionView x:Name="ads"
ItemsSource="{Binding AdLogEntries}"
SelectionMode="Single"
SelectionChangedCommand="{Binding AdSelectionChangedCommand}"
SelectedItem="{Binding SelectedAd, Mode=TwoWay}"
Margin="12,0">
详细介绍XAML:
<Label Text="{Binding AdDetail.Name}"/>
为AdDetail发布XAML
<CollectionView x:Name="ads"
ItemsSource="{Binding AdLogEntries}"
SelectionMode="Single"
SelectionChangedCommand="{Binding AdSelectionChangedCommand}"
SelectedItem="{Binding SelectedAd, Mode=TwoWay}"
Margin="12,0">
public DetailPage(AdLogEntry detail)
{
this.BindingContext = new AdDetailViewModel(adDetail);
InitializeComponent();
}
<Label Text="{Binding AdDetail.Name}"/>