Forum Xamarin Xamarin.Forms

Expand ListView Item

Hey there. Im currently trying to work with the ListView. Right now I am trying to make ListView Items expandable.

Like I can see a full Text right now but I want to cut it short and make it to fully visible when selected.
I tried to add to my NewsEntry class something like:
string cutText {get { return Text.Substring(0,10) + " tapMeToMakeMeBig";}}
but I realized that I could not get to solution with this.

then I tried this:

`

MessagingCenter.Subscribe<WriteArticle, NewsEntry>(this, "Spiderman", (p, item) =>
        {
        var finishedNews = item as NewsEntry;
            var finNewCut = item as NewsEntry;
            if (finNewCut.Text.Length > 8)
            {
                finNewCut.Text = finNewCut.Text.Substring(0, 5) + "tapMeToMakeMeBig";
                newsEntries.Insert(0, finNewCut);
            }
            else  newsEntries.Insert(0, finishedNews);
            NewsList.ItemsSource = newsEntries;
        });

`

and assume that this could work out but I do not know how to go from here. My Idea in theory would be:
When I tap on an Item that is cut off the finNewCut.Text would change to the finishedNews.Text of finishedNews.
But with this way I would not have the full text anymore since it is never added to newsEntries which means the complete Text is lost. This probably could be fixed if I create a second ObservableCollection<NewsEntry> noCuts = new ObservableCollection<NewsEntry>(); but this does not seem like a nice solution.

That made me guess that there probably is a way smarter/easier solution but I am blind to the obvious.

This is my Code so far:

.cs:
`

public partial class NewsPage : ContentPage
{
ObservableCollection newsEntries = new ObservableCollection();

    public NewsPage()
    {
        InitializeComponent();

        NewsList.ItemsSource = newsEntries;

        MessagingCenter.Subscribe<WriteArticle, NewsEntry>(this, "Spiderman", (p, item) =>
        {
        var finishedNews = item as NewsEntry;
            newsEntries.Insert(0, finishedNews);
            NewsList.ItemsSource = newsEntries;
        });
    }

    public async void AddArticle_Clicked(object sender, EventArgs e)
    {
        await Navigation.PushModalAsync(new WriteArticle());
    }

    public void Test_Clicked(object sender, EventArgs e)
    {
        newsEntries.Add(new NewsEntry { Title = "This", Text = "That " }); 
         newsEntries.Insert(0, new NewsEntry{Title="hey", Text="yo345678910"});
        NewsList.ItemsSource = newsEntries;
    }
}

public class NewsEntry
{
    public string Title { get; set; }
    public string Text { get; set; }
}`

and this is my xaml:

`

<ContentPage.Content>

    <StackLayout>

        <Button Clicked="Test_Clicked" Text="Test">
        </Button>

        <ListView x:Name="NewsList" HasUnevenRows="true">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Frame BorderColor="Black">
                            <StackLayout>
                                <StackLayout>
                                    <Image HeightRequest="50" WidthRequest="50" Source="https://xamarin.com/content/images/pages/forms/example-app.png" />
                                </StackLayout>
                                <Label Text="{Binding Title}" />
                                <Label Text="{Binding Text}" />
                            </StackLayout>
                        </Frame>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <Button x:Name="addArticle" Clicked="AddArticle_Clicked" Text="AddArticle" />

    </StackLayout>
</ContentPage.Content>`

Best Answer

Answers

  • ClintBClintB Member ✭✭

    Look into the DataTemplateSelector. Here's the official MicrosoftDoc. Make sure you have the HasUnevenRows set to true on the ListView.

  • axbeitaxbeit Member ✭✭
    edited November 2018

    @ClintB said:
    Look into the DataTemplateSelector. Here's the official MicrosoftDoc. Make sure you have the HasUnevenRows set to true on the ListView.

    Thank you so far. Im got a new problem I cannot solve.

        public class NewsEntry
        {
            public string Title { get; set; }
           // public string Text { get; set; }
    
            public TestDTS tex { get; set; }
        }
    
        public class TestDTS : DataTemplateSelector
        {
           // public DataTemplate titel { get; set; }
            public DataTemplate texd { get; set; }
    
            public DataTemplate texdCut 
            {
                get { return texd.ToString().Substring(0,5);}
            }
    
            protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
            {
                return item.ToString().Length > 7 ? texdCut : texd;
            }
        }
    

    I cannot make the Class TestDTS work. I tried a few things but I don´t know how I can select only a part of the text. If I change one thing to fix it I get a problem somewhere else in the class. Mainly because I cannot convert the type. And the return of "OnSelectTemplate" has to be DataTemplate

    edit
    I found another way:

                        MessagingCenter.Subscribe<WriteArticle, NewsEntry>(this, "Spiderman", (p, item) =>
                        {
                            var finishedNews = item as NewsEntry;
                            if (finishedNews.TextFull.Length > 18)
                            {
                                finishedNews.Text = finishedNews.TextCut;
                            }
                            else finishedNews.Text = finishedNews.TextFull;
                            newsEntries.Insert(0, finishedNews);
                        });
    
            //....
    
                    public void NewsList_Selected(Object sender, SelectedItemChangedEventArgs e)
                    {
                        newsEntries[0].Text = newsEntries[0].TextFull;
                        NewsList.ItemsSource = null;
                        NewsList.ItemsSource = newsEntries;
                    }
    
            //....
    
                public class NewsEntry
                {
                    public string Title { get; set; }
                    public string Text { get; set; }
    
                    public string TextFull { get; set; }
                    public string TextCut 
                    {
                        get { return TextFull.Substring(0, 10) + " but wait. theres more"; }
                    }
                }
    

    But for refreshing the ListView I set it´s ItemsSource to null and back to newsEntries. Is there another way?

Sign In or Register to comment.