【问题标题】:How do i add items to a observablecollection from another list view如何从另一个列表视图将项目添加到 observablecollection
【发布时间】:2020-07-31 20:12:32
【问题描述】:

您好,我是 Xamarin 表单的初学者,需要一些帮助。我试过到处寻找这种方法。

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

但我不知道如何做到这一点,任何帮助将不胜感激。

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

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;
    }

【问题讨论】:

  • 你必须向我们展示你的实际代码,而不是给我们一个模糊的描述。这两个 ListView 是否都在同一页面上?还是不同的页面?请阅读minimal reproducible exampleHow to Ask
  • 对不起,我是新手。它们在不同的页面上。下面附上代码
  • 还没有。还在苦苦挣扎:(
  • 你可以在下面查看,用法大致如下。
  • 您尝试过使用 MessagingCenter 吗?

标签: xamarin xamarin.forms


【解决方案1】:

所以这就是我所做的。我不得不改变一点。 添加的鸟名需要进入一个空白列表。所以我在这里创建了一个新的 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】:

    您可以使用MessagingCenter 来实现此目的。

    使用MessagingCenter.SendBirdPagesAddToList_Clicked 方法中传递新数据

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

    例如:

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

    public partial class BirdListAZ : ContentPage
    {
      public ObservableCollection<string> Birdsadded { get; set; } = new ObservableCollection<string>();
      public BirdListAZ()
        {
            InitializeComponent();
            blistview.ItemsSource = GetBirds();
            MessagingCenter.Subscribe<BirdListAZ, string>(this, "Add", async (sender, arg) =>
            {
                Birdsadded.Add(arg);// when you click add button in other page,it will handle this
            });
        }
    
    }
    

    在您要添加数据的页面中:

    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 birdname = xxxx;
            MessagingCenter.Send<BirdListAZ, string>(this, "Add",birdname );
        }
    }
    

    【讨论】:

    • 我似乎无法做到这一点。您在其中指定“birdlistmodel bird = xxx;//这是您要添加到列表中的内容”我希望添加 BirdNames,但我无法让它工作。
    • 你可以检查更新,如果你想添加鸟名(字符串类型),你只需将birdlistmodel bird = xxx更改为string BirdNames并更改MessagingCenter.Send&lt;BirdListAZ,string&gt;MessagingCenter.Subscribe&lt;BirdListAZ, string&gt;
    【解决方案3】:

    好的,所以我让它在某种程度上发挥了作用。我没有创建和写入 txt 文件,然后在 mybirdlist 页面中读取它。这是我写入文本文件的地方

           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");
            }
    

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

     public myBirdList()
            {
                
                localPath = Path.Combine(FileSystem.AppDataDirectory, birdfile);
                
                string text = "";
                using (var reader = new System.IO.StreamReader(localPath))
                {
                    text = reader.ReadToEnd();
                }
                InitializeComponent();
    
                birdlistview.ItemsSource = new List<birdlistmodel>
                {
                    new birdlistmodel {Voellist = text }
    
                };
            }
            const string birdfile = "birdlist.txt";
    
            string localPath;
        }
    

    【讨论】:

    • 您可以将其标记为解决方案。它可能对其他人有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-18
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    相关资源
    最近更新 更多