【问题标题】:Bind listview image source to image (Sqlite/ UWP/ C#)将listview图像源绑定到图像(Sqlite/ UWP/ C#)
【发布时间】:2016-03-29 07:56:57
【问题描述】:

以下代码可以将图像从数据库添加到列表视图,但是我想使用图像源将图像属性绑定到 XAML 中的图片,而不是使用 listview1.Items.Add。可以轻松修改此代码以执行此操作还是我必须以另一种方式进行。希望这不是一个愚蠢的问题,我将不胜感激。

public async void showImage()
    {
        var query = GetAll();

        foreach (var stuff in query)
        {
            string FileName;
            FileName = stuff.RecipeImage;
            var file = await
            Windows.Storage.KnownFolders.PicturesLibrary.GetFileAsync(FileName);
            var stream = await file.OpenReadAsync();
            var bitmapImage = new BitmapImage();
            bitmapImage.SetSource(stream);

            Image ctrlImage = new Image();
            ctrlImage.Source = bitmapImage;
            ctrlImage.Height = 50;
            ctrlImage.Width = 50;
            ctrlImage.Stretch = Stretch.UniformToFill;

            listView1.Items.Add(ctrlImage);
        }
    }

我需要将图像添加到已用于我的数据库的项目源中,其中包含:

public class AddRecipe
{
    [PrimaryKey,AutoIncrement]
    public int ID { get; set; }
    public string RecipeName { get; set; }
    public string RecipeImage { get; set; }
} 

 <ListView x:Name="listView" HorizontalAlignment="Left" Height="493" Margin="725,60,0,0" VerticalAlignment="Top" Width="528" IsItemClickEnabled="True" SelectionMode="None" ItemClick="listView_SelectionChanged" FontSize="26.667">
        <ListView.ItemTemplate>
            <DataTemplate >
                <StackPanel Orientation="Vertical"  Margin="4">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding RecipeName}" Foreground="Black"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding MealType}" Foreground="Black"/>
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

【问题讨论】:

    标签: c# image sqlite listview uwp


    【解决方案1】:

    我们可以使用ListView.ItemTemplate来设置DataTemplate用来显示每个项目,并将所有图像放入ObservableCollection&lt;BitmapImage&gt;作为ListViewItemsSource。然后在DataTemplate中,我们可以使用Bind来设置Image.Source。以下是一个简单的示例:

    在 XAML 中,设置 DataTemplate{x:Bind} 以显示图像。

    <ListView ItemsSource="{x:Bind ImgList}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="BitmapImage">
                <Image Width="50"
                       Height="50"
                       Source="{x:Bind }"
                       Stretch="UniformToFill" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

    ImgList 在代码隐藏中定义,它被定义为ObservableCollection&lt;BitmapImage&gt;,所以DataTemplateDataTypeBitmapImage,因为我只是将整个BitmapImage 对象绑定到Image.Source 所以在这里只需使用Source="{x:Bind }"

    代码隐藏可能如下:

    public sealed partial class MainPage : Page
    {
        public ObservableCollection<BitmapImage> ImgList = new ObservableCollection<BitmapImage>();
    
        public MainPage()
        {
            this.InitializeComponent();
        }
    
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            showImage();
        }
    
        public async void showImage()
        {
            var query = GetAll();
    
            foreach (var stuff in query)
            {
                string FileName = stuff.RecipeImage;
                var file = await Windows.Storage.KnownFolders.PicturesLibrary.GetFileAsync(FileName);
                var stream = await file.OpenReadAsync();
                var bitmapImage = new BitmapImage();
                bitmapImage.SetSource(stream);
    
                ImgList.Add(bitmapImage);
            }
        }
    }
    

    此外,我注意到您正在从图片库获取图像。如果这些图片是你的应用之前存储的,那么将它们存储在应用数据中会更好,因为这样可以更容易地绑定,并且在图片库中,这些图片可以很容易地被用户删除。

    要将图像存储在应用数据中,我们可以使用ApplicationData.Current.LocalFolder 检索应用的本地数据文件夹。例如,将选中的图片复制到本地数据文件夹中:

    //This method copies selected image into local data folder and returns new file's name.
    public async Task<string> CopySelectedImage()
    {
        FileOpenPicker openPicker = new FileOpenPicker();
        openPicker.ViewMode = PickerViewMode.Thumbnail;
        openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
    
        openPicker.FileTypeFilter.Clear();
        openPicker.FileTypeFilter.Add(".bmp");
        openPicker.FileTypeFilter.Add(".jpg");
        openPicker.FileTypeFilter.Add(".jpeg");
        openPicker.FileTypeFilter.Add(".png");
    
        var file = await openPicker.PickSingleFileAsync();
    
        if (file != null)
        {
            var localFolder = ApplicationData.Current.LocalFolder;
            var newCopy = await file.CopyAsync(localFolder, file.Name, NameCollisionOption.GenerateUniqueName);
            return newCopy.Name;
        }
        else
        {
            return null;
        }
    }
    

    然后我们可以使用如下代码来检索图像并创建BitmapImage

    var path = await CopySelectedImage();
    var bitmapImage = new BitmapImage(new Uri($"ms-appdata:///local/{path}"));
    

    更新:

    我想你的项目源中有RecipeImage,那么你可以在你的DataTemplate 中添加一个Image 控件并将RecipeImage 绑定到它的SourceImageConverter,如下所示:

    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin="4" Orientation="Vertical">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Foreground="Black" Text="{Binding RecipeName}" />
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Foreground="Black" Text="{Binding MealType}" />
                </StackPanel>
                <Image Width="50"
                       Height="50"
                       Source="{Binding RecipeImage,
                                        Converter={StaticResource ImageConverter}}"
                       Stretch="UniformToFill" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
    

    ImageConverter 用于将string 转换为BitmapImage,因为您的RecipeImage 定义为string,但Image.Source 需要BitmapImage。在Binding中使用之前,我们需要先将其设置为StaticResource

    <Page.Resources>
        <local:ImageConverter x:Key="ImageConverter" />
    </Page.Resources>
    

    ImageConverter的代码可能喜欢:

    public class ImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            string FileName = value as string;
            var file = Windows.Storage.KnownFolders.PicturesLibrary.GetFileAsync(FileName).AsTask().Result;
            var stream = file.OpenReadAsync().AsTask().Result;
            var bitmapImage = new BitmapImage();
            bitmapImage.SetSource(stream);
            return bitmapImage;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
    

    【讨论】:

    • 感谢您的回答,它确实在列表视图中显示图像,但是通过将 itemsource 添加到 ImgList 它现在不会显示列表中的项目名称,因为它已绑定到数据库等作为 ,您知道我如何将两者同时显示吗?谢谢
    • @myf33tsmell,你没有必要使用ImgList,因为你有一个项目来源。您可以使用带有值转换器的项目源(假设它包含RecipeImage)与其他人一起显示图像。我更新了我的答案以展示如何做到这一点。希望对您有所帮助。
    • 它的工作,现在看起来很简单,但非常感谢你的帮助
    【解决方案2】:

    简单

    xaml
    
    <ListView Name="listView1">
         <ListView.ItemTemplate>
              <DataTemplate>
                   <Grid>
                        <Image Source="{Binding}" Height="50" Width="50" Stretch="UniformToFill" />
                   </Grid>
               </DataTemplate>
          </ListView.ItemTemplate>
    </ListView>
    
    и в коде добавляем List<BitmapImage>
    
    List<BitmapImage> data_list = new List<BitmapImage>();
    
    foreach (var stuff in query)
            {
                string FileName;
                FileName = stuff.RecipeImage;
                var file = await
                Windows.Storage.KnownFolders.PicturesLibrary.GetFileAsync(FileName);
                BitmapImage bitmapImage;
                using (var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
                {
                    bitmapImage = new BitmapImage();
                    bitmapImage.SetSource(stream);
                }
    
              data_list.Add(bitmapImage);
            }
    
     listView1.ItemsSource = data_list; 
    

    然后我们只需将数据填充到我们的 ListView 中

    【讨论】:

      猜你喜欢
      • 2016-09-15
      • 2016-12-07
      • 2014-09-26
      • 1970-01-01
      • 1970-01-01
      • 2020-02-12
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      相关资源
      最近更新 更多