如何从另一个列表视图将项目添加到可观察的集合

时间:2020-07-06 15:28:22

标签: xamarin xamarin.forms

嗨,我是Xamarin表格的初学者,需要一些帮助。我尝试到处寻找这种方法。

我有很多动物名字的List视图。单击某个项目时,它将显示有关该特定动物的更多信息。我在每个动物信息页面上添加了一个按钮。我想单击该“添加”按钮,然后将动物名称添加到另一个“列表”视图中。

但是我对如何做到这一点有所保留,任何帮助将不胜感激。

这是代码后面的第一个列表页面

public partial class BirdListAZ : ContentPage
    {
        IEnumerable<birdlistmodel> GetBirds(string searchText = null)
        {
            var birds = new List<birdlistmodel>
            {
                new birdlistmodel (){Id = 1, BirdNames = "Apalis, Bar-throated" }, 
                new birdlistmodel (){Id = 2, BirdNames = "Apalis, Yellow-breasted"},//there are alot more birds here
        
            };
            if (String.IsNullOrWhiteSpace(searchText))
                return birds;
            var lowerBirds = searchText.ToLower();
            return birds.Where(c => c.BirdNames.ToLower().StartsWith(lowerBirds));
        }

        public BirdListAZ()
        {
            InitializeComponent();
            blistview.ItemsSource = GetBirds();
        }

        private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
        {
            blistview.ItemsSource = GetBirds(e.NewTextValue);
        }

        private void blistview_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var birds = e.SelectedItem as birdlistmodel;
            Navigation.PushAsync(new BirdPages(birds.BirdNames, birds.BirdSelect));
        }
    }
}

这是该代码后面的内容页面

 <ScrollView HeightRequest="3000">
            <StackLayout>
                <SearchBar 
                    TextChanged="SearchBar_TextChanged"
                    Placeholder="Search Bird"
                    PlaceholderColor="Gray"
                    HorizontalTextAlignment="Center"
                    FontSize="Small"
                    FontAttributes="Italic"
                    VerticalOptions="Center" HorizontalOptions="Start"/>
                <ListView x:Name="blistview" BackgroundColor ="AliceBlue" HasUnevenRows="True" ItemSelected="blistview_ItemSelected">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <StackLayout Orientation="Horizontal" Padding="5">
                                    <Label Text="{Binding BirdNames}" HorizontalOptions="StartAndExpand" VerticalOptions="Center"/>
                                    
                                </StackLayout>
                            </ViewCell>
                        </DataTemplate>

                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
        </ScrollView>

在列表上单击项目时,它将在单独的页面中显示该信息 内容页面

   <ContentPage.Content>
        <StackLayout>
            <Label x:Name="BirdNameCall" FontSize="30" FontAttributes="Bold"
                VerticalOptions="StartAndExpand" 
                HorizontalOptions="CenterAndExpand" />
            <Button Text="+" x:Name="AddToList" VerticalOptions="Center" HorizontalOptions="Center" WidthRequest="200" HeightRequest="100" 
                    FontSize="30" BackgroundColor="Transparent" Clicked="AddToList_Clicked"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

这就是我所做的。我知道filewritealltext每次都会创建一个新文件。我如何才能添加到该文件,这样就不会创建新文件?

 public BirdPages(string BirdNames, Button BirdSelect)
        {
            InitializeComponent();

            BirdNameCall.Text = BirdNames;
            AddToList = BirdSelect;
            localPath = Path.Combine(FileSystem.AppDataDirectory, birdfile);
        }

        const string birdfile = "birdlist.txt";

        string localPath;
        private void AddToList_Clicked(object sender, EventArgs e)
        {
            string BirdNames = BirdNameCall.Text;
            File.WriteAllText(localPath, BirdNames);
            DisplayAlert(BirdNames, "added to list", "Ok");
        }

所以当我填充列表视图时它可以工作,但是它将是每行一个字母,而不是一行中的整个字符串

public partial class myBirdList : ContentPage
    { 
   
        public myBirdList()
        {
            InitializeComponent();
            localPath = Path.Combine(FileSystem.AppDataDirectory, birdfile);

            birdlistview.ItemsSource = File.ReadAllText(localPath);



        }
        const string birdfile = "birdlist.txt";
        string localPath;
    }

4 个答案:

答案 0 :(得分:0)

您可以使用MessagingCenter来实现。

使用absolute通过relative的{​​{1}}方法传递新数据

然后,您将在另一个要使用MessagingCenter.Send方法添加新项目的页面中获得回调。在回调方法中,您可以将新数据添加到新的列表视图中。

例如:

要在列表视图页面中显示列表并添加新数据。

AddToList_Clicked

您要添加数据的页面中:

BirdPages

答案 1 :(得分:0)

这就是我所做的。我不得不改变一点。 添加的“鸟类名称”需要转到空白列表。所以我在这里创建了一个新的Observable Collection。这就是需要添加鸟名的地方。

    public partial class myBirdList : ContentPage
    {
       public ObservableCollection<string> Birdsadded { get; set; } = new ObservableCollection<string>();



        public myBirdList()
        {
            InitializeComponent();
            BindingContext = this;

            MessagingCenter.Subscribe<BirdPages, birdlistmodel>(this, "Add", (sender, arg) =>
           {
               Birdsadded.Add(arg.ToString());
           });

        }
    }
}

然后,发件人就是我遇到问题的地方。而且不知道如何发送鸟名。

    public partial class BirdPages : ContentPage
    {
        public BirdPages(string BirdNames, Button BirdSelect)
        {
            InitializeComponent();

            BirdNameCall.Text = BirdNames;
            AddToList = BirdSelect;
        }

        private void AddToList_Clicked(object sender, EventArgs e)
        {
            birdlistmodel bird = xxx// this is what i don't understand, what should be added here 
            MessagingCenter.Send<BirdListAZ, birdlistmodel>(this, "Add", bird );
        }
    }
}

感谢您的宝贵时间和宝贵的投入。

答案 2 :(得分:0)

好的,所以我已经实现了这一点,我没有收到任何错误,但是没有用。 这就是现在的代码。发送页面:

    public partial class BirdPages : ContentPage
    {
        public BirdPages(string BirdNames, Button BirdSelect)
        {
            InitializeComponent();

            BirdNameCall.Text = BirdNames;
            AddToList = BirdSelect;
        }

        private void AddToList_Clicked(object sender, EventArgs e)
        {
            string BirdNames = BirdNameCall.Text;
            MessagingCenter.Send<BirdPages, string>(this, "Add", BirdNames);
            DisplayAlert("Added", BirdNameCall.Text , "Ok");
        }
    }
}

这是订阅页面:

    public partial class myBirdList : ContentPage
    {
        ObservableCollection<string> birdlist { get; set; } = new ObservableCollection<string>();
       



        public myBirdList()
        {
            InitializeComponent();
            birdlistview.ItemsSource = birdlist;

            

            MessagingCenter.Subscribe<BirdPages, string>(this, "Add", (sender, arg) =>
           {
             birdlist.Add(arg);
           });

        }
    }
}

在Xamarin中发送页面:

            x:Class="AppSFari.Kwandwe_Pakage.KwandweBirds.BirdPages">
    <ContentPage.Content>
        <StackLayout>
            <Label x:Name="BirdNameCall" FontSize="30" FontAttributes="Bold"
                VerticalOptions="StartAndExpand" 
                HorizontalOptions="CenterAndExpand" />
            <Button Text="+" x:Name="AddToList" VerticalOptions="Center" HorizontalOptions="Center" WidthRequest="200" HeightRequest="100" 
                    FontSize="30" BackgroundColor="Transparent" Clicked="AddToList_Clicked"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

出现新列表视图的订阅页面:

             x:Class="AppSFari.Kwandwe_Pakage.Lists.myBirdList">
    <ContentPage.Content>
        <StackLayout>
            <ListView x:Name="birdlistview" ItemsSource="{Binding birdlist}" BackgroundColor ="AliceBlue" HasUnevenRows="True">
            
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

希望这会有所帮助。没有错误,但是当我按下按钮时列表没有被填充。该列表保持空白。

答案 3 :(得分:0)

好的,所以我可以在某种程度上使用它。我不是在创建和写入txt文件,而是在mybirdlist页面中读取该文件。这是我写文本文件的地方

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-12">
  <div class="d-block">
    <strong>Product code:</strong>
    <span class="">L00335.06</span>
  </div>
  <div class="d-block">
    <span class="">L00335.06</span>
    <span class="card-text text-muted">Catalog number: ALF-L00335-06</span>
  </div>
  <strong class="text-capitalize">quantity:</strong> 5g&nbsp;
  <strong class="text-capitalize">CAS:</strong> 2981-10-4&nbsp;
  <div class="d-block mt-2 checkoutHide">
    <span class="js-delete-item pointer" data-entrynumber="0" data-quantity="1">
      <strong class="icon_Remove font_icon"></strong> 
      Delete
    </span>
  </div>
</div>

然后我从中读取一个列表。我最后一个问题是如何将每个名称读入标签。现在,所有添加的鸟都显示在一个标签中。是否可以不重复名称?这是代码

       public BirdPages(string BirdNames, Button BirdSelect)
        {
            InitializeComponent();

            BirdNameCall.Text = BirdNames;
            AddToList = BirdSelect;
            localPath = Path.Combine(FileSystem.AppDataDirectory, birdfile);
        }

        const string birdfile = "birdlist.txt";

        string localPath;
        private void AddToList_Clicked(object sender, EventArgs e)
        {
            string BirdNames = BirdNameCall.Text;
            using (var writer = new StreamWriter(localPath, true))
                {
                writer.WriteLine(BirdNames);
            }
            DisplayAlert(BirdNames, "added to list", "Ok");
        }