【问题标题】:How to add Data to SQLite offline database table and display it on listView Xamarin如何将数据添加到 SQLite 离线数据库表并在 listView Xamarin 上显示
【发布时间】:2019-11-16 19:51:58
【问题描述】:

我正在 Xamarin.Forms 中做一个天气应用项目。在成功将用户添加到数据库并在“登录”时验证现有用户之后,现在我正在努力在 SQLite 数据库中添加一个城镇(带有 3 个变量),然后在内容页面上的 ListView 中显示信息。 问题是,当我单击“天气”按钮时,ListView 中没有显示任何内容,并且触发了第二个捕获 - Temp = "Unable to get Weather";

让我们从我的城镇模型开始:

public class Town
{       
    [PrimaryKey]
    public int ID { get; set; }
    public string TownName { get; set; }
    public string Temp { get; set; }
    public string searchTime { get; set; }

    public Town() { }
}

创建这个简单的类后,我正在实现一个控制器类来处理城镇数据:

SQLiteConnection database;

    public SearchHistoryDataController()
    {

        database = DependencyService.Get<ISQLite>().GetConnection();

        database.CreateTable<Town>();

    }

    IEnumerable<Town> orderItemCollection;
    public IEnumerable<Town> OrderItemCollection
    {
        get
        {
            if (orderItemCollection == null)
                orderItemCollection = GetTowns();
            return orderItemCollection;
        }
    }

    public IEnumerable<Town> GetTowns()
    {
        // Changing the database table items as ObservableCollection
        var table = (from i in database.Table<Town>() select i);
        ObservableCollection<Town> TownList = new ObservableCollection<Town>();
        foreach (var town in table)
        {
            TownList.Add(new Town()
            {
                ID = town.ID,
                TownName = town.TownName,
                Temp = town.Temp,
                searchTime = town.searchTime
            });
        }
        return TownList;
    }

    public Town GetTown(int id)
    {

        return database.Table<Town>().FirstOrDefault(t => t.ID == id);

    }


    public void DeleteTown(int id)
    {

        database.Delete<Town>(id);

    }

    public string AddTown(Town town)
    {
        var data = database.Table<Town>();
        var d1 = data.Where(x => x.TownName == town.TownName && x.searchTime == town.searchTime).FirstOrDefault();

        if (d1 == null)
        {           

            database.Insert(town);

            return "Successfully Added";

        }
        else
        {
            return "Invalid Town id Exist";
        }
    }

从这里开始,最后两件事是: 创建一个城镇,插入一些信息,将城镇存储在数据库中,每当单击“显示天气”按钮时,这都是在命令中完成的。有代码:

                 //Get weather information for the Weather view
            Temp = $"{weatherRoot?.MainWeather?.Temperature ?? 0}°C";
            Condition = $"{weatherRoot?.Weather?[0]?.Description ?? string.Empty}";
            Name = $"{weatherRoot.Name}, {weatherRoot.System.Country}";
            Humidity = $"{weatherRoot.MainWeather.Humidity}%";
            Pressure = $"{weatherRoot.MainWeather.Pressure} hpa";
            Clouds = $"{weatherRoot.Clouds.CloudinessPercent}%";
            Wind = $"{weatherRoot.Wind.Speed} m/s";


            town.TownName = $"{weatherRoot.Name}";
            town.Temp = Temp;
            town.searchTime = DateTime.Parse(weatherRoot.Date).ToLocalTime().ToString("g");;

            //history database push               
            try
            {
                SearchHistoryDataController searchHistoryDataController = new SearchHistoryDataController();
                var returnvalue = searchHistoryDataController.AddTown(town);

                if (returnvalue == "Sucessfully Added")
                {

                    Console.WriteLine("Success");

                }
                else
                {
                    Console.WriteLine("Fail");
                }
            }
            catch (Exception es)
            {
                Debug.WriteLine(es.Message);
            }


            await TextToSpeech.SpeakAsync(Temp + " " + Condition);
            IsBusy = false;

        }
        catch (Exception ex)
        {
            Temp = "Unable to get Weather";
            Debug.WriteLine(ex.Message);
        }
        finally
        {
            IsBusy = false;
        }
    }

最终的 - XAML 文件的结构如下:

 <Grid>
        <Image HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Aspect="AspectFill" Source="gradientBack.png"/>
        <StackLayout Padding="10" Spacing="10">
            <StackLayout Orientation="Horizontal" Spacing="20" HorizontalOptions="Center" VerticalOptions="Start" Margin="5,20">
                <Label Text="Search History" FontSize="20" FontAttributes="Bold" VerticalOptions="Center" TextColor="White" HorizontalOptions="Center"/>
            </StackLayout>
            <ListView ItemsSource="{Binding OrderItemCollection}"
              HasUnevenRows="True"
              CachingStrategy="RecycleElement"
              IsPullToRefreshEnabled="True"
              RefreshCommand="{Binding GetWeatherCommand}"
              IsRefreshing="{Binding IsBusy, Mode=OneWay}"
              RowHeight="66"
              x:Name="ListViewTide">
                <ListView.SeparatorColor>
                    <OnPlatform x:TypeArguments="Color" iOS="Transparent"/>
                </ListView.SeparatorColor>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <Frame BackgroundColor="White" BorderColor="#F0F0F0" Padding="5" Margin="0,0,0,5" HasShadow="False">
                                <Grid HeightRequest="50" HorizontalOptions="FillAndExpand" VerticalOptions="Start">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <Label Text="{Binding DisplayTide}" TextColor="#800080" FontSize="15"
                                           FontAttributes="Bold"
                                           Style="{DynamicResource ListItemTextStyle}"/>
                                    <StackLayout Grid.Column="2" Orientation="Horizontal" Margin="20,0" HorizontalOptions="End" VerticalOptions="Center">
                                        <Label Text="{Binding DisplayTime}" TextColor="Black" FontSize="15" FontAttributes="None" VerticalOptions="Center"/>
                                    </StackLayout>
                                </Grid>
                            </Frame>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </Grid>

这个想法是在点击“天气”按钮时自动更新历史列表。历史将在文本字段中存储城镇名称、准确时间和温度。 该列表不会用于其他任何内容,它是一个选项卡。

非常感谢!

【问题讨论】:

  • 导致“无法获取天气”消息的实际异常是什么?
  • 这是关于天气信息的。它工作正常,如果我删除有关城镇数据库的部分,则不会触发此异常。
  • 杰森,你能不能冷静一点。没有异常消息,因为不存在现有错误。如果有异常消息可以帮助您解决问题,我一定会分享。我已经解决了这个问题。 BR

标签: c# android sql visual-studio xamarin


【解决方案1】:

我确实解决了这个问题。第一个问题是这一行:town.searchTime = DateTime.Parse(weatherRoot.Date).ToLocalTime().ToString("g");

由于无法访问此日期变量,导致命令失败。我修复了它:town.searchTime = DateTime.Now.ToString();

接下来——如何显示保存在 SQLite 数据库中的数据:

将 Town 插入数据库,然后将其轮询出来并存储在 TownList 下:

town.TownName = $"{weatherRoot.Name}";
                town.Temp = Temp;
                town.searchTime = DateTime.Now.ToString();

                //history database push               
                try
                {      
                    var returnvalue = searchHistoryDataController.AddTown(town);

                    if (returnvalue == "Sucessfully Added")
                    {

                        Console.WriteLine("Success");
                    }
                    else
                    {
                        Console.WriteLine("Fail");
                    }                
                }
                catch (Exception es)
                {
                    Debug.WriteLine(es.Message);
                }

                TownList = searchHistoryDataController.OrderItemCollection;

最后但同样重要的是 XAML 和 SearchHistoryController:

<ListView ItemsSource="{Binding TownList}"
              x:Name="ListViewTide">
                <ListView.SeparatorColor>
                    <OnPlatform x:TypeArguments="Color" iOS="Transparent"/>
                </ListView.SeparatorColor>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <Frame BackgroundColor="White" BorderColor="#F0F0F0" Padding="5" Margin="0,0,0,5" HasShadow="False">
                                <Grid HeightRequest="50" HorizontalOptions="FillAndExpand" VerticalOptions="Start">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <Label Text="{Binding TownName}" TextColor="#757575" FontSize="13" VerticalOptions="Center" Margin="20,0"/>
                                    <Label Grid.Column="1" Text="{Binding searchTime}" TextColor="Black" FontSize="10" FontAttributes="None" HorizontalOptions="Center" VerticalOptions="Center"/>
                                    <StackLayout Grid.Column="2" Orientation="Horizontal" Margin="20,0" HorizontalOptions="End" VerticalOptions="Center">
                                        <Label Text="{Binding Temp}" TextColor="Black" FontSize="25" FontAttributes="Bold" VerticalOptions="Center"/>
                                    </StackLayout>
                                </Grid>
                            </Frame>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

从SQL拉取信息到List的方法:

 IEnumerable<Town> orderItemCollection;
        public IEnumerable<Town> OrderItemCollection
        {
            get
            {
                if (orderItemCollection == null)
                    orderItemCollection = GetTowns();
                return orderItemCollection;
            }
        }

        public IEnumerable<Town> GetTowns()
        {
            // Changing the database table items as ObservableCollection
            var table = (from i in database.Table<Town>() select i);
            ObservableCollection<Town> TownList = new ObservableCollection<Town>();
            foreach (var town in table)
            {
                TownList.Add(new Town()
                {
                    ID = town.ID,
                    TownName = town.TownName,
                    Temp = town.Temp,
                    searchTime = town.searchTime
                });
            }
            return TownList;
        }

并且只是提醒大家,您的对象的模型,如果它将存储在 SQL 中,请始终包含AutoIncrement

[PrimaryKey, AutoIncrement]
        public int ID { get; set; }

希望这会对某人有所帮助。 :)

【讨论】:

  • 能否将您的回复标记为答案,以便其他有类似问题的人可以从您的回答中获得帮助?谢谢。
  • 嗨,我正要这样做。将您自己的回复标记为答案是有限制的,我必须等待 24 小时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-14
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多