Xamarin CarouselView,在另一个页面中显示 currentItem 详细信息。

Jiale Xue - MSFT 46,126 信誉分 Microsoft 供应商
2024-06-06T06:37:04.2733333+00:00

我正在开发歌词应用程序。它有两个选项卡。“歌词”选项卡和“详细信息”选项卡。

歌词选项卡是一个轮播视图,仅显示歌曲的 ID、标题和歌词。

滑动页面时,我想在“详细信息”选项卡中显示当前歌曲的所有其他信息,例如作词人、专辑、年份等。

歌词选项卡完美地显示所有歌曲的ID,标题和歌词。但是“详细信息”选项卡始终为空。

在 SongModel 中:

public class Song
{
   public string id {get; set;}
   public string title { get; set; }
   public string lyrics { get; set; }
   public string lyricist { get; set; }
   public string album{ get; set; }
   public string genre{ get; set; }
}

在 SongViewModel 中:

class SongsViewModel : BaseViewModel
{
   public Song currentsong { get; set; }
   public List<Song> songlist { get; private set; } 
}

歌曲是从 json 文件分析的,并绑定到 lyrics.xaml 中 DataTemplate 的 ItemsSource。而且效果很好。

在Lyrics.xaml.cs中,检测当前项目更改(带有 CarouselView 的歌词选项卡):

public partial class Lyrics : ContentPage
{
   public Lyrics()
   {
       InitializeComponent();
       BindingContext = new SongsViewModel();
   }

   public void OnCurrentItemChanged(object sender, CurrentItemChangedEventArgs e)
   {
       var item = e.CurrentItem as Song;
       ((SongsViewModel)this.BindingContext).currentsong = item;
   }
}

在 Details.xaml 页中,

<ListView ItemsSource="{Binding currentsong}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Label FontSize="17" HorizontalOptions="Start" TextColor="Black" LineBreakMode="WordWrap">
                <Label.Text>
                    <MultiBinding StringFormat="{}Lyricist : {0};&#x0a;Album: {1}&#x0a;Genre : {2}">
                        <Binding Path="lyricist"/>
                        <Binding Path="album"/>
                        <Binding Path="genre"/>
                    </MultiBinding>
                </Label.Text>
            </Label>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

在Details.xaml.cs页面中

 public partial class Details : ContentPage
 {
        public Details()
        {
            InitializeComponent();
            BindingContext = new SongsViewModel();
        }
 }

请告诉我这里出了什么问题。

谢谢。

Note:此问题总结整理于: Xamarin CarouselView, display currentItem details in another page.

Xamarin
Xamarin
用于使用 .NET 和 C# 构建 Android 和 iOS 应用的 Microsoft 开源应用平台。
14 个问题
C#
C#
一种面向对象的类型安全的编程语言,它起源于 C 语言系列,包括对面向组件的编程的支持。
185 个问题
0 个注释 无注释
{count} 票

接受的答案
  1. Hui Liu-MSFT 48,556 信誉分 Microsoft 供应商
    2024-06-06T07:50:09.1233333+00:00

    欢迎来到我们的 Microsoft 问答平台!

    您的代码中存在几个问题。

    导航到页面时,您为 model 创建了一个新实例,因此 没有 的值。DetailsSongsViewModelcurrentsong

      public Details()  
      {  
          InitializeComponent();  
          BindingContext = new SongsViewModel();  
      }  
    

    当您在页面中设置 listView 时,它的类型应该是列表而不是 。<ListView ItemsSource=“{绑定当前歌曲}”>ItemsSourceDetailscurrentsong 根据您的需要,当我们导航到页面时,我们可以将所选项目的数据传递到页面:DetailsDetails

    In page Lyrics:

            public void OnCurrentItemChanged(object sender, CurrentItemChangedEventArgs e)  
        {  
            Song item = e.CurrentItem as Song;  
           // ((SongsViewModel)this.BindingContext).currentsong = item;  
            Navigation.PushAsync(new Details(item));  
        } 
    

    In page Details,we can get the item from the constructor :

       public partial class Details : ContentPage  
        {  
            Song currentSong;  
      
            public Details(Song song)  
            {  
                InitializeComponent();  
      
                currentSong = song;  
                BindingContext = currentSong;  
            }  
      
        }  
    

    Details.xaml

    <ContentPage.Content>  
        <StackLayout>  
            <Label FontSize="17" HorizontalOptions="Start" TextColor="Black" LineBreakMode="WordWrap">  
                <Label.Text>  
                    <MultiBinding StringFormat="{}Lyricist : {0};&#x0a;Album: {1}&#x0a;Genre : {2}">  
                        <Binding Path="lyricist"/>  
                        <Binding Path="album"/>  
                        <Binding Path="genre"/>  
                    </MultiBinding>  
                </Label.Text>  
            </Label>  
        </StackLayout>  
    </ContentPage.Content>  
    
    

    Update

    It has two tabs. Lyrics tab and Details tab.

    If you have two tabs, you can achieve this function by the following steps:(I have tested on my side ,it works properly)

    add static for the currentsong in model SongsViewModel, then page Lyrics and Details will share the same field currentsong:

     public class SongsViewModel  
    { // set static for currentsong   
        public static Song currentsong { get; set; }  
        public List<Song> songlist { get; private set; }  
    
        public SongsViewModel()  
        {  
            songlist = new List<Song>();  
            songlist.Add(new Song { title = "title1", lyricist = "Jack", album = "Album1", genre = "classical" });  
            songlist.Add(new Song { title = "title2", lyricist = "hello", album = "Album2", genre = "Country" });  
            songlist.Add(new Song { title = "title3", lyricist = "May", album = "Album3", genre = "pop" });  
        }  
    }  
    

    make model Song implement interface INotifyPropertyChanged, when the value of currentsong changes, the UI will refresh automatically.

      public class Song: INotifyPropertyChanged  
     {  
         public string id { get; set; }  
         public string title { get; set; }  
    
         public string lyrics { get; set; }  
    
    
        // public string lyricist { get; set; }  
    
         string _lyricist;  
         public string lyricist  
         {  
             set { SetProperty(ref _lyricist, value); }  
    
             get { return _lyricist; }  
         }  
    
    
        // public string album { get; set; }  
    
         string _album;  
         public string album  
         {  
             set { SetProperty(ref _album, value); }  
    
             get { return _album; }  
         }  
    
    
         //public string genre { get; set; }  
         string _genre;  
         public string genre  
         {  
             set { SetProperty(ref _genre, value); }  
    
             get { return _genre; }  
         }  
    
         bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)  
         {  
             if (Object.Equals(storage, value))  
                 return false;  
    
             storage = value;  
             OnPropertyChanged(propertyName);  
             return true;  
         }  
    
         protected void OnPropertyChanged([CallerMemberName] string propertyName = null)  
         {  
             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));  
         }  
    
         public event PropertyChangedEventHandler PropertyChanged;  
     }  
    
    

    Lyrics.xaml.cs

    public partial class Lyrics : ContentPage
    {
    SongsViewModel viewModel;
    
    
     public Lyrics()  
     {  
         InitializeComponent();  
         viewModel = new SongsViewModel();  
         BindingContext = viewModel;  
     }  
    
     public void OnCurrentItemChanged(object sender, CurrentItemChangedEventArgs e)  
     {  
         Song item = e.CurrentItem as Song;  
    
         SongsViewModel.currentsong = item;  
     }  
    }
    

    Lyrics.xaml

    <ContentPage.BindingContext>
    tabbedpagewithnavigationpage:SongsViewModel</tabbedpagewithnavigationpage:SongsViewModel>
    </ContentPage.BindingContext>
    <ContentPage.Content>
    <StackLayout>
    <CarouselView ItemsSource="{Binding songlist}" CurrentItemChanged="OnCurrentItemChanged">
    <CarouselView.ItemsLayout>
    <LinearItemsLayout Orientation="Vertical" />
    </CarouselView.ItemsLayout>
    <CarouselView.ItemTemplate>
    <DataTemplate>
    <StackLayout>
    <Frame HasShadow="True"
    BorderColor="DarkGray"
    CornerRadius="5"
    Margin="20"
    HeightRequest="100"
    HorizontalOptions="Center"
    VerticalOptions="CenterAndExpand">
    <StackLayout>
    <Label Text="{Binding title }"
    FontAttributes="Bold"
    FontSize="Large"
    HorizontalOptions="Center"
    VerticalOptions="Center" />
    <Label
    Text="{Binding lyricist }"
    HeightRequest="150"
    WidthRequest="150"
    HorizontalOptions="Center" />
    
    
                             </StackLayout>  
                         </Frame>  
                     </StackLayout>  
                 </DataTemplate>  
             </CarouselView.ItemTemplate>  
         </CarouselView>  
     </StackLayout>  
    </ContentPage.Content>
    

    Details.xaml.cs

     public partial class Details : ContentPage
    {
    
    
     Song song;  
     public Details()  
     {  
         InitializeComponent();  
    
     }  
    
     protected override void OnAppearing()  
     {  
         base.OnAppearing();  
    
         song = SongsViewModel.currentsong;  
         BindingContext = song;  
     }  
    }
    

    Details.xaml <ContentPage.Content>

    <StackLayout>
    <Label FontSize="17" HorizontalOptions="Start" TextColor="Black" LineBreakMode="WordWrap">
    <Label.Text>
    <MultiBinding StringFormat="{}Lyricist : {0}; Album: {1} Genre : {2}">
    <Binding Path="lyricist"/>
    <Binding Path="album"/>
    <Binding Path="genre"/>
    </MultiBinding>
    </Label.Text>
    </Label>
    </StackLayout>
    </ContentPage.Content>
    

    如果回复有帮助,请点击“接受答案”并点赞。 注意:如果您想接收此线程的相关电子邮件通知,请按照我们文档中的步骤启用电子邮件通知。

    1 个人认为此答案很有帮助。
    0 个注释 无注释

0 个其他答案

排序依据: 非常有帮助

你的答案

问题作者可以将答案标记为“接受的答案”,这有助于用户了解已解决作者问题的答案。