I am implementing the FlowListView NuGet package for a custom listview with multiple columns.
(NuGet package link: https://www.nuget.org/packages/DLToolkit.Forms.Controls.FlowListView/)
Everything is displayed as it should. But the app is getting very slow. On looking further in the Live Visual Tree I found out that the list items in the FlowListView are loading infinitely. I don't know what is causing it.
Can anyone tell me why it is happening, and how to stop it?
XAML:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
xmlns:vm="clr-namespace:FlowDemo.ViewModels"
x:Class="FlowDemo.MainPage">
<ContentPage.BindingContext>
<vm:MainViewModel />
</ContentPage.BindingContext>
<StackLayout>
<flv:FlowListView FlowColumnCount="2"
RowHeight="50"
SeparatorVisibility="Default"
HasUnevenRows="false"
FlowItemsSource="{Binding Items}" >
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Frame Margin="10" Padding="0" CornerRadius="6" HasShadow="True">
<Label Text="{Binding}" HorizontalOptions="Center" VerticalOptions="Center" />
</Frame>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
</StackLayout>
</ContentPage>
View Model:
using System.Collections.ObjectModel;
namespace FlowDemo.ViewModels
{
public class MainViewModel
{
public ObservableCollection<string> Items { get; set; } = new ObservableCollection<string>() { "Item 1", "Item 2", "Item 3", "Item 4", };
}
}
Code Behind:
using DLToolkit.Forms.Controls;
using Xamarin.Forms;
namespace FlowDemo
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
FlowListView.Init();
}
}
}
EDIT:
I'm using Visual Studio 2022 and .Net Standard 2.0. I'm also using PropertyChanged.Fody for implementing INotifyPropertyChanged.
Screenshot:
Click here to view image
The problem might be because MainPage USES FlowListView during InitializeComponent.
UPDATE Moving Init (as suggested below) did not fix.
Need to call FlowListView.Init() BEFORE use it.
You COULD do this simply by moving it earlier in MainPage constructor:
public MainPage()
{
FlowListView.Init();
InitializeComponent();
}
But then if you change to a different starting page, you might forget to call it. Therefore, a better place is in
App.xaml.cs:
public App()
{
...
FlowListView.Init();
...
}
Related
I have a simple view model where one property contains a model, and another property contains a list of models.
I am able to bind the "Test" model's properties without an issue but I'm not able to get the XAML to recognize that "ListModel" contains a list with its own properties. I have looked at several examples for how to set up the view model and initialize the list correctly before binding it to the view, and while the XAML understands that "ListModel" is a property, I can't get it to recognize that it's a list, and thus it will not compile so that I can at least see if it isn't the intellisense that could be failing for whatever reason.
This is the view model in question with the list named "ListModel"
public class TestViewModel
{
public TestModel Test { get; } = new TestModel();
public List<TestListModel> ListModel { get; set; }
public TestViewModel()
{
Initialize();
}
public void Initialize()
{
ListModel = new List<TestListModel>();
ListModel.Add(new TestListModel
{
ListProp1 = "First",
ListProp2 = "Second",
ListProp3 = "Third"
});
}
}
This is the Model that is being put into a list. It seems like the view isn't seeing these properties.
public class TestListModel
{
public string ListProp1 { get; set; }
public string ListProp2 { get; set; }
public string ListProp3 { get; set; }
}
This is my XAML Currently.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
xmlns:local="clr-namespace:ViewModels"
x:DataType="local:TestViewModel"
>
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<!--This works-->
<Entry Text="{Binding Test.Property1}"/>
<Entry Text="{Binding Test.Property2}"/>
<Entry Text="{Binding Test.Property3}"/>
<!--This does not work-->
<ListView
ItemsSource="{Binding ListModel}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding ListProp1}"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
For anyone stumbling in on this: Jason in the comments has answered the question. The fix was simply to remove x:DataType from the top of the XAML, though I did not remove the "xmlns:local" from it.
What I had was a View Model that had more than just one model in it, which seemed to upset the intellisense when removing x:DataType. Removing it originally prevented the application from compiling because it couldn't find the properties I had in the XAML. Once I cleaned and rebuilt the solution it compiled and worked without a hitch.
The view and the viewmodel are often connected through data bindings defined in XAML. The BindingContext for the view is usually an instance of the viewmodel.So I think you forget to connect these two elements with BindingContext.
Code behind View:
public partial class MainPage : ContentPage
{
TestViewModel tv = new TestViewModel();
public MainPage()
{
InitializeComponent();
BindingContext = tv;
}
}
Code in Xaml:
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<!--This works-->
<Entry Text="{Binding Test.Property1}"/>
<Entry Text="{Binding Test.Property2}"/>
<Entry Text="{Binding Test.Property3}"/>
<!--This works too-->
<ListView
HasUnevenRows="True"
ItemsSource="{Binding ListModel}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<VerticalStackLayout>
<Label Text="{Binding ListProp1}"/>
<Label Text="{Binding ListProp2}"/>
<Label Text="{Binding ListProp3}"/>
</VerticalStackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</VerticalStackLayout>
</ScrollView>
Outcome:
Reference link.
I was able to fix the error while also keeping the compiled bindings in place by making the ItemSource bind to a List with a private backing field. It seems like the compiler is unable to resolve the list correctly without the private property being there. After i added listModel it compiled. So the issue seems to be that the setter is missing.
private List<TestListModel> listModel;
public List<TestListModel> ListModel { get => listModel; set => listModel = value; }
I already tried, string to ImageSource in my model but still I did not get image to display in ImageCell.
If I try this line of code <Image Source="https://img.icons8.com/carbon-copy/2x/user.png"></Image>, image displays fine.
Model
public class Contact
{
public string Name { get; set; }
public string Status { get; set; }
public ImageSource ImageUri { get; set; }
}
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="App1.ListPage">
<ContentPage.Content>
<StackLayout>
<ListView x:Name="listView" SeparatorVisibility="Default" SeparatorColor="Blue">
<ListView.ItemTemplate>
<DataTemplate>
<!--<TextCell Text="{Binding Name}" Detail="{Binding Status}" TextColor="Accent" DetailColor="Beige"></TextCell>-->
<!--<TextCell Text="{Binding Name}" Detail="{Binding Status}"></TextCell>-->
`<ImageCell Text="{Binding Name}" Detail="{Binding Status}" ImageSource="{Binding ImageUri}`"></ImageCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--<Image Source="https://img.icons8.com/carbon-copy/2x/user.png"></Image>-->
</StackLayout>
</ContentPage.Content>
</ContentPage>
XAML.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ListPage : ContentPage
{
public ListPage()
{
InitializeComponent();
listView.ItemsSource = new List<Contact>
{
new Contact{ Name="Monkey D. Luffy", ImageUri=ImageSource.FromUri(new Uri("https://img.icons8.com/carbon-copy/2x/user.png"))},
new Contact{ Name="Monkey D. Dragon",
ImageUri=ImageSource.FromUri(new Uri("https://img.icons8.com/carbon-copy/2x/user.png"))},
new Contact{ Name="Portgas D. Ace",
ImageUri=ImageSource.FromUri(new Uri("https://img.icons8.com/carbon-copy/2x/user.png")), Status="Hello World!"}
};
}
}
just did two tests on my playground.
I kicked off with a blank Xamarin.Forms project (only one MainPage there) in VS2019, then
updated the XF nuget package to 4.7.0.1142.
pasted your code.
remove two extra ` characters in your xaml code snippet.
It's working.
Then, I tried the string property in the model class like this:
public string ImageUri { get; set; }
And also set string value in xaml.cs class like this:
new Contact{ Name="", ImageUri="https://xxx.png"}
It's also working.
Not sure about the issue, but your code is fine anyway.
Try to use this nuget https://github.com/luberda-molinet/FFImageLoading for images. Is the best !!
As I mentinoned in image discriptions, I have update register form and I want to update groups of my User, But for now I can do that with just one group. I should be able to add this User to multiple groups. For that I need multiple Pickers and like in the images I need to pop up pickers in the screen dynamically according to needs of the User. Maybe the User will want to select one group or maybe want to three groups.
What I am asking here is, How can I add this pickers or any UI element dynamically while app is running. And last question is, user can ,maybe, want to remove that second or third picker from the view. Deselect I mean. How can I do that. Thanks for ideas and codes.
There are many solutions which can implement it . For example you can check the following code .
1. create a custom view which contains the Picker
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="xxx.PickerView">
<ContentView.Content>
<Grid HeightRequest="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.9*" />
<ColumnDefinition Width="0.1*" />
</Grid.ColumnDefinitions>
<Picker Grid.Column="0" x:Name="picker" Title="Select Groups" TitleColor="Red" />
<Label Grid.Column="1" Text="Canel" TextColor="Red">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" NumberOfTapsRequired="1" />
</Label.GestureRecognizers>
</Label>
</Grid>
</ContentView.Content>
</ContentView>
using System;
using System.Collections.ObjectModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace xxx
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PickerView : ContentView
{
public ObservableCollection<string> pickerSource { get; set; }
//public PickerView()
//{
// InitializeComponent();
//}
public PickerView(ObservableCollection<string> source)
{
InitializeComponent();
picker.ItemsSource = source;
}
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
var stack = this.Parent as StackLayout;
stack.Children.Remove(this);
}
}
}
in content page
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<StackLayout x:Name="pickerStack" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
</StackLayout>
<Button Text="+ add another group" Clicked="Button_Clicked" />
</StackLayout>
private void Button_Clicked(object sender, EventArgs e)
{
var source = new ObservableCollection<string>() {"111","222","333" };
pickerStack.Children.Add(new PickerView(source));
}
I am attempting to use CarouselView for the first time and is kind of struck with it. I have XAML defined as follows
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
x:Class="cSixty.Xam.Views.MainPage"
Title="MainPage">
<ContentPage.Content>
<StackLayout>
<Label Text="Name" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
<cv:CarouselView ItemsSource="{Binding Zoos}">
<cv:CarouselView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Name}" />
</DataTemplate>
</cv:CarouselView.ItemTemplate>
</cv:CarouselView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
The ViewModel has a Collection defined as follows.
public MainPageViewModel()
{
Zoos = new ObservableCollection<Zoo>
{
new Zoo
{
Name = "Woodland Park Zoo"
},
new Zoo
{
Name = "Cleveland Zoo"
},
new Zoo
{
Name = "Phoenix Zoo"
}
};
}
Where Zoo is defined as
public class Zoo
{
public string Name { get; set; }
}
My issue is that the Carousel just doesn't show up. Its all empty. Could someone guide me ?
Finally got it working, just thought will share it in case someone else runs into same situation.
You need install the Nuget Package in your Droid Project (or whatever platform you are using) as well. Previously, I had installed in my Portable Library only.
I have taken a label in .xmal file.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListDemo.TableView">
<StackLayout>
<Label Text="Above TableView"></Label>
<TableView>
<TableView.Root>
<TableSection Title="Test">
<EntryCell Label="EntryCell"></EntryCell>
<TextCell Text="Test" Detail="Text Detail"></TextCell>
<ViewCell>
<ViewCell.View>
<StackLayout Orientation="Horizontal" >
<BoxView Color="Red"></BoxView>
<StackLayout>
<Label Text="{Binding Receivename}"></Label>
<Label Text="News URL 1"></Label>
</StackLayout>
<BoxView x:Name="boxView" Color="Blue" ></BoxView>
</StackLayout>
</ViewCell.View>
</ViewCell>
</TableSection>
</TableView.Root>
</TableView>
</StackLayout>
I want to set the Label data from .cs file.
namespace ListDemo
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TableView : ContentPage
{
public TableView()
{
InitializeComponent();
public string Receivename = "Hello";
}
}
}
Please let me know , how can I set the dynamic data of Label . What to write in .cs file .
Thanks in advance.
First, you can only bind to properties. So you would need:
public string Recievename { get; set; }
Second, you are setting this data in the constructor, when it should be within the scope of the actual class.
You can, however, set the value of the property in the constructor. Just not define it there.
Update per request:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TableView : ContentPage
{
public string Receivename { get; set; }
public TableView()
{
InitializeComponent();
BindingContext = this; //Need to set data context as well, if not defined in XAML
Receivename = "Hello";
}
}
I also suggest you look more into binding, property notification, etc. This blog on xamarin should give you a hint: https://blog.xamarin.com/introduction-to-data-binding/