【问题标题】:Images saved in database are not displaying in the Home.xaml page in Xamarin Forms app保存在数据库中的图像未显示在 Xamarin Forms 应用程序的 Home.xaml 页面中
【发布时间】:2019-12-17 10:23:21
【问题描述】:

在我的 Xamarin Forms 应用程序中,Home.xaml 在保存到数据库后不显示图像。在调试时,我可以看到,bytes[] 正在 PlayerImage 上针对播放器显示。在 xaml 中,我有 Source="{Binding PlayerImage}" 但无法弄清楚不显示的原因。断点处显示的字节是否正确?

// Home.xaml

<ContentPage.Resources>
        <DataTemplate x:Key="playerTemplate">
            <ContentView>
                <StackLayout  Margin="5,5" BackgroundColor="#584961">
                    <Image x:Name="{PlayerImage}" Source="{Binding PlayerImage}" WidthRequest="25" HeightRequest="25"/>
                    <Label Text="{Binding FullName}" Font="Bold,18" TextColor="White"/>
                    <Label Text="{Binding Mobile}" Font="Bold,13" TextColor="White"/>
                    <Label Text="{Binding SoccerPosition}" Font="Bold,13" TextColor="White"/>
                    <Button Text="Remove Player"  Clicked="DeleteButton_OnClicked" WidthRequest="120" HeightRequest="50"  TextColor="White" BackgroundColor="#d6b947"></Button>
                </StackLayout>
            </ContentView>
        </DataTemplate>
    </ContentPage.Resources>
    <StackLayout Margin="5">
        <CollectionView x:Name="collectionview"
         ItemTemplate="{StaticResource playerTemplate}">
            <!--span here decides the number of items shows in one line. Now is 3 items one line-->
            <CollectionView.ItemsLayout>
                <GridItemsLayout Orientation="Vertical" Span="3" />
            </CollectionView.ItemsLayout>
        </CollectionView>
    </StackLayout>

// PlayerDetails.cs

public byte[] PlayerImage { get; set; }

//Home.xaml.cs

public void DisplayDetails()
        {
            List<PlayerDetails> details = (from x in conn.Table<PlayerDetails>() select x).ToList();
            for (int i = 0; i < details.Count; i++)
            {
                players.Add(details[i]);
            }

        }

// 也添加了我的 PlayerDetails.cs 类

public class PlayerDetails : INotifyPropertyChanged
    {
        [PrimaryKey, AutoIncrement]
        public int id { get; set; }
        public string Password { get; set; }
        public string ConfirmPassword { get; set; }
        public byte[] PlayerImage { get; set; }

    string fullname;
        string mobile;
        string soccerposition;
        string email;

        public PlayerDetails()
        {

        }

        [Ignore]
        public Image Image
        {
            get
            {
                var image = new Image();
                image.Source = ImageSource.FromStream(() => new MemoryStream(PlayerImage));
                return image;
            }
            set
            {

               //PlayerImage = Convert.ToByteArray(value.Source);
               //Bitmap.FromStream(inStream);
            }
        }


        public string FullName
        {
            set
            {
                if (fullname != value)
                {
                    fullname = value;

                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("FullName"));
                    }
                }
            }
            get
            {
                return fullname;
            }
        }

        public string Mobile
        {
            set
            {
                if (mobile != value)
                {
                    mobile = value;

                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("Mobile"));
                    }
                }
            }
            get
            {
                return mobile;
            }

        }
        public string SoccerPosition
        {
            set
            {
                if (soccerposition != value)
                {
                    soccerposition = value;

                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("SoccerPosition"));
                    }
                }
            }
            get
            {
                return soccerposition;
            }
        }
        public string Email
        {
            set
            {
                if (email != value)
                {
                    email = value;

                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("Email"));
                    }
                }
            }
            get
            {
                return email;
            }

        }

       //public ImageSource Source { get; internal set; }

       public event PropertyChangedEventHandler PropertyChanged;

    }

【问题讨论】:

  • 首先,byte[] 不是有效的 ImageSource。其次,byte[0] 表示您的数组长度为 0,这意味着您的图像数据没有被加载。最后,将图像存储在数据库中通常不是一个好主意。
  • 好的,从List&lt;PlayerDetails&gt; details我们如何获取字节然后转换成图像,找到转换代码public Image byteArrayToImage(byte[] byteArrayIn) { MemoryStream ms = new MemoryStream(byteArrayIn); Image returnImage = Image.FromStream(ms); return returnImage; }
  • 如果您将图像存储在文件系统中,然后将路径存储在数据库中,这将容易得多。然后,您可以只使用图像源绑定的字段路径。但正如我之前提到的,您的 PlayerImage 属性似乎是一个空数组,所以我首先要弄清楚为什么会发生这种情况。
  • 谢谢,我会检查它为什么存储为空数组
  • @Jason 现在我成功地将bytearray 保存到 SQlite 数据库中。现在如何将 bytearray 转换回 Image 然后传递给 Source="{Binding PlayerImage}"

标签: xamarin xamarin.forms


【解决方案1】:

如果您从 Xamarin.Forms 中的 byte[] 数组加载图像,您可以尝试以下代码:

c#代码:

byte[] bitmapData = ...;
ImageSource imageSource= ImageSource.FromStream(() => new MemoryStream(bitmapData));

PlayerImage.Source = imageSource;//binding in code

xaml 代码:

<Image x:Name="PlayerImage"  WidthRequest="25" HeightRequest="25"/>

或者在xaml中绑定

<image Source="{Binding imageSource}"/>

注意:

  1. 我发现x:Name="{PlayerImage}" 不正确。 应该是:x:Name="PlayerImage" 而不是 x:Name="{PlayerImage}"

  2. 您只需要使用以下绑定方法中的一种即可:

     PlayerImage.Source = imageSource;// in code
    

还有

 <Image x:Name="PlayerImage" Source="{Binding imageSource}" />

更新:

您可以尝试使用从 IValueConverter 派生的转换器,它可以根据字节数组创建图像。

ByteArrayToImageSourceConverter.cs

public class ByteArrayToImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        ImageSource retSource = null;
        if (value != null)
        {
            byte[] imageAsBytes = (byte[])value;
            var stream = new MemoryStream(imageAsBytes);
            retSource = ImageSource.FromStream(() => stream);
        }
        return retSource;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

PlayerDetails.cs

 public class PlayerDetails
  {
    // other fields

    public byte[] PlayerImage { get; set; }
  }

xaml(a usage example):

 <ContentPage.Resources>
    <ResourceDictionary>
        <myformapp1:ByteArrayToImageSourceConverter x:Key="ByteArrayToImage" 
/>
    </ResourceDictionary>
  </ContentPage.Resources>

 <StackLayout Margin="5">
    <CollectionView x:Name="collectionView"
                    ItemsSource="{Binding YoudataList}"> <!--changd to your dataList-->
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="10">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Image Grid.RowSpan="2"  
                           x:Name="PlayerPic"
                           Source="{Binding PlayerImage, Converter={StaticResource ByteArrayToImage}}"
                           Aspect="AspectFill"
                           HeightRequest="60" 
                           WidthRequest="60" />
                    <Label Grid.Column="1" 
                           Text="test1" 
                           FontAttributes="Bold" />
                    <Label Grid.Row="1"
                           Grid.Column="1" 
                           Text="test2"
                           FontAttributes="Italic" 
                           VerticalOptions="End" />
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</StackLayout>

【讨论】:

  • 这是我的 Home.page.cs 代码,用于显示播放器 ..List&lt;PlayerDetails&gt; details = (from x in conn.Table&lt;PlayerDetails&gt;() select x).ToList(); for (int i = 0; i &lt; details.Count; i++) { players.Add(details[i]); byte[] byteImage = details[i].PlayerImage; PlayerImage.Source = ImageSource.FromStream(() =&gt; new MemoryStream(byteImage)); },以下是我的 Home.xaml,用于显示 &lt;Image x:Name="{PlayerImage}" Source="{Binding PlayerImage}" WidthRequest="25" HeightRequest="25"/&gt;
  • 它说`PlayerImage.Source = ImageSource.FromStream(() => new MemoryStream(byteImage));`在上下文中不存在
  • 我也添加了PlayerDetails.cs 课程。
  • 你只需要使用我在note中提到的一种方式绑定,你可以尝试在xaml中删除Source="{Binding imageSource}"
  • 您可以尝试使用其他变量名。
猜你喜欢
  • 1970-01-01
  • 2021-03-29
  • 2016-06-15
  • 2021-11-05
  • 2020-09-05
  • 2020-03-02
  • 2019-01-19
  • 2014-09-05
  • 1970-01-01
相关资源
最近更新 更多