i am trying to pass data from a child page to to a parent class this is the parent
namespace App11
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class OrderedItemsPage : ContentPage
{
public string aSize;
public string size, Main, Milk;
public List<String> sizeList = new List<string>();
public List<String> mainList = new List<string>();
public List<String> milkList = new List<string>();
public ObservableCollection<ElementsViewModel> elements { get; set; }
public void OrderedItemsPageBlank()
{
aSize = "";
Main = "";
Milk = "";
}
public OrderedItemsPage ()
{
InitializeComponent ();
}
public void displayToList()
{
elements = new ObservableCollection<ElementsViewModel>();
for(int i = 0;i< mainList.Count;i++)
{
string Coffee = sizeList[i] + " : " + mainList[i];
elements.Add(new ElementsViewModel
{
Image = "icon.png",
Coffee = Coffee,
Details = "$2.50 each"
});
}
listView.ItemsSource = elements;
}
}
}
and this is the child class...
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App11.OrderedItemsPage">
<ContentPage.Content>
<StackLayout >
<!--Top Section-->
<ListView x:Name="listView" RowHeight="60">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout
Orientation="Horizontal"
HorizontalOptions="Fill">
<Image x:Name="BgImage" Source="{Binding Image}"
AbsoluteLayout.LayoutBounds="250.25, 0.25, 50, 50"/>
<StackLayout Orientation="Vertical">
<Label Text="{Binding Coffee}"
FontSize="24"
AbsoluteLayout.LayoutBounds="0.25, 0.25, 400, 40"
></Label>
<Label Text="{Binding Details}"
AbsoluteLayout.LayoutBounds="50, 50, 200, 25"
></Label>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackLayout Orientation="Horizontal">
<!--Second half-->
<Button
x:Name="AddButton"
Text="Add Drink"
VerticalOptions="EndAndExpand"
HorizontalOptions="CenterAndExpand"
Clicked="addDrinkButtonClick">
</Button>
<Button Text="Add Food"
VerticalOptions="EndAndExpand"
HorizontalOptions="CenterAndExpand">
</Button>
</StackLayout>
<!--third half ( cause thats a thing)-->
<StackLayout Orientation="Vertical">
<Button Text="Process Order"
VerticalOptions="EndAndExpand"
HorizontalOptions="CenterAndExpand"
></Button>
</StackLayout>
</StackLayout>
</ContentPage.Content>
i basically need to receive the data, now when i debug the program the information is passed through perfect but when i populate is into the list view it does not display when i run the app?
any help would be awesome, thanks
This probably is the culprit: elements = new ObservableCollection<ElementsViewModel>();.
Do not new a ObservableCollection every time. This will cause the binding to updating the UI and your changes will not show up. Just instantiate the elements once: public ObservableCollection<ElementsViewModel> elements { get; set; } = new ObservableCollection<ElementsViewModel>(); and clear it every time you need an empty one. Then just add items to it one-by-one.
A helpful package here is the MVVM Helpers by James Montemagno. It has the ObservableRangeCollection, which lets you replace whole ranges and such, saving you some foreaches.
Related
I have the following firebase database:
And let's say I want to display all the values inside "Rest1". How can I do it?
I currently use the following code to make the connection and display everything inside the database.
display.xaml.cs
public ObservableCollection<MyDatabaseRecord> DatabaseItems { get; set; } = new
ObservableCollection<MyDatabaseRecord>();
FirebaseClient firebaseClient = new FirebaseClient("link");
private void tabelaRestLoad()
{
var collection = firebaseClient
.Child("Menus")
.AsObservable<MyDatabaseRecord>()
.Subscribe((dbevent) =>
{
if (dbevent != null)
{
DatabaseItems.Add(dbevent.Object);
}
});
}
display.xaml:
<StackLayout Margin="15,0,15,5" BackgroundColor="Transparent">
<CollectionView ItemsSource="{Binding DatabaseItems}" SelectionMode="Single" SelectionChanged="OnCollectionViewSelectionChanged" BackgroundColor="Transparent">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame BackgroundColor="#fff2d8" HorizontalOptions="Center" Margin="0,10,0,5" Padding="2" WidthRequest="350" CornerRadius="10">
<StackLayout BackgroundColor="#fff2d8">
<Label Text="{Binding Plate1}" TextColor="Black" FontAttributes="Bold" HorizontalOptions="Center" Margin="0, 5, 0, 0" FontSize="20"/>
<Label Text="{Binding Plate2}" TextColor="Black" HorizontalOptions="Center" Margin="0, 0, 0, 15" FontSize="17"/>
<Label Text="{Binding Plate3}" TextColor="Black" Margin="10, 0, 0, 0" FontSize="15"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>
MyDatabaseRecord.cs:
public class MyDatabaseRecord
{
public string Plate1 { get; set; }
public string Plate2 { get; set; }
public string Plate3 { get; set; }
}
As I said, this code I'm using returns every "Plate" value from both Rest1 and Rest2 inside "Menus" child. My question here is, how can I only display the values inside Rest1, for example, instead of all of them?
Thanks in advance
The minimal code change would be to use a query on the key:
var collection = firebaseClient
.Child("Menus")
.OrderByKey()
.EqualTo("Rest1")
.AsObservable<MyDatabaseRecord>()
...
I have a CollectionView with a few items in it. I'm trying to adjust the size of the CollectionView to be just big enough to fit all of its children. Right now, it's much larger than the amount of children it has.
The Blue color represents the size of the CollectionView. As you can see, it's well beyond the size of it's children. I'd like it to fit them perfectly, or at the very least be closer to the same size.
I don't have any height requests on any of the elements on the page, including the CollectionView.
Here's my code. It's not particularly pretty at the moment, but it's a work in progress.
<StackLayout>
<CollectionView x:Name="assessmentsCollectionView"
BackgroundColor="Blue">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Spacing="10"
Padding="5">
<Frame CornerRadius="5"
Padding="0"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal">
<Frame Padding="5"
CornerRadius="0"
WidthRequest="50">
<Label Text="{Binding TypeLetter}"
TextColor="#37474f"
FontSize="24"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"/>
</Frame>
<StackLayout Padding="10">
<Label Text="{Binding Name}"
TextColor="Black"
FontSize="24"/>
<StackLayout Orientation="Horizontal">
<Image Source="calendarIcon.png"
WidthRequest="12"
HeightRequest="12"/>
<Label Text="{Binding Date}"
FontSize="12"
TextColor="Gray"/>
</StackLayout>
</StackLayout>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
I changed CollectionView to FlexLayout with BindableLayout.ItemsSource and BindableLayout.ItemTemplate
What was previously
<CollectionView.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
What was done
<FlexLayout Direction="Column"
x:Name="MessagesList"
AutomationId="MessagesList"
BindableLayout.ItemsSource="{Binding Messages}" >
<BindableLayout.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</BindableLayout.ItemTemplate>
</FlexLayout>
For me works well, no need to set Height for item or FlexLayout, all are dynamic
If you have little rows in Collectionview, you can set a value to collectionView.HeightRequest. when item increase, the height will increase as well.
I create a property called.RowHeigth. If I add item in the CollectionView(with AddCommand), RowHeigth will increase.
<StackLayout>
<CollectionView
x:Name="assessmentsCollectionView"
BackgroundColor="Blue"
HeightRequest="{Binding rowHeigth}"
ItemsSource="{Binding letters}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="5" Spacing="10">
<Frame
Padding="0"
CornerRadius="5"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal">
<Frame
Padding="5"
CornerRadius="0"
WidthRequest="50">
<Label
FontSize="24"
HorizontalTextAlignment="Center"
Text="{Binding TypeLetter}"
TextColor="#37474f"
VerticalTextAlignment="Center" />
</Frame>
<StackLayout Padding="10">
<Label
FontSize="24"
Text="{Binding Name}"
TextColor="Black" />
<StackLayout Orientation="Horizontal">
<Image
HeightRequest="12"
Source="c1.png"
WidthRequest="12" />
<Label
FontSize="12"
Text="{Binding Date}"
TextColor="Gray" />
</StackLayout>
</StackLayout>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Button
x:Name="btn1"
Command="{Binding AddCommand}"
Text="btn1" />
</StackLayout>
public partial class Page4 : ContentPage
{
public Page4()
{
InitializeComponent();
this.BindingContext = new letterviewmodel(); ;
}
}
public class letterviewmodel: INotifyPropertyChanged
{
public ObservableCollection<lettermodel> letters { get; set; }
private int _rowHeigth;
public int rowHeigth
{
get { return _rowHeigth; }
set
{
_rowHeigth = value;
RaisePropertyChanged("rowHeigth");
}
}
public ICommand AddCommand { protected set; get; }
public letterviewmodel()
{
letters = new ObservableCollection<lettermodel>()
{
new lettermodel(){TypeLetter="A",Name="letter 1",Date="2021-01-01"},
new lettermodel(){TypeLetter="B",Name="letter 2",Date="2021-01-01"},
new lettermodel(){TypeLetter="C",Name="letter 3",Date="2021-01-01"}
};
rowHeigth = letters.Count * 100 ;
AddCommand = new Command<lettermodel>(async (key) => {
letters.Add(new lettermodel() { TypeLetter = "D", Name = "test letter ", Date = "2021-01-01" });
rowHeigth = letters.Count * 100 ;
});
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class lettermodel
{
public string TypeLetter { get; set; }
public string Name { get; set; }
public string Date { get; set; }
}
Don't forget toimplement INotifyPropertyChanged interface, to inotify data update.
So, I have trouble binding data to my MasterDetailView. I'm getting no errors, and my code seems to be correct, based on sources that I have found online. However, nothing populates my MasterDetailView..
<MasterDetailPage.Master>
<ContentPage Title="Menu" BackgroundColor="#9BD2AD" x:Name="test">
<StackLayout Orientation="Vertical">
<Label Text="MENU" TextColor="#106073" HorizontalOptions="Center" FontAttributes="Bold" Margin="0,20,0,0" FontSize="Large"/>
<ListView ItemsSource="{Binding listOfItems}" x:Name="navigationDrawerList" RowHeight="55" SeparatorVisibility="None"> <!--ItemSelected="NavigationDrawerList_ItemSelected"-->
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand" Orientation="Vertical" Padding="20,10,0,0">
<Label Text="{Binding Title}" TextColor="#106073" HorizontalTextAlignment="Start" FontSize="Medium"/>
<BoxView WidthRequest="2" HeightRequest="1" BackgroundColor="Beige"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
Cs
private List<MasterPageItem> listOfItems = new List<MasterPageItem>();
MasterPageItem pages = new MasterPageItem();
public SlideMenu()
{
InitializeComponent();
test.BindingContext = getPages();
}
public List<MasterPageItem> getPages()
{
listOfItems.Add(new MasterPageItem("TEST1", typeof(Test1)));
listOfItems.Add(new MasterPageItem("TEST2", typeof(Test2)));
return listOfItems;
}
MasterPageItem class
public class MasterPageItem
{
public string Title { get; set; }
public Type TargetType { get; set; }
public MasterPageItem()
{
}
public MasterPageItem(string Title, Type TargetType)
{
this.Title = Title;
this.TargetType = TargetType;
}
}
i'm trying to bind a command to a button inside a listView, but without success. I follow all other answers posted here, like this one:
Xamarin Forms Button Command binding inside a ListView
The actual result is that nothing happens. A thing that i notice is that visual studio, when i type after x:Reference suggests me just GridWebcam, like if it doesn't see other reference elements. What can i do?
Here my code:
<ContentPage
...
x:Name="WebcamList">
<ContentPage.Resources>
...
<ContentPage.Content>
<ListView ItemsSource="{Binding ListOfWebcam}"
SeparatorVisibility="None"
CachingStrategy="RecycleElement"
RowHeight="250"
VerticalOptions="FillAndExpand"
x:Name="ListWebcam">
<ListView.Header>
<StackLayout x:Name="HeaderStackLayout"
Padding="5,25,0,30"
Orientation="Horizontal"
HorizontalOptions="FillAndExpand">
<Label x:Name="LabelHeader"
Text="Webcam:"
FontSize="Large"
FontAttributes="Bold"
TextColor="{x:Static statics:Palette.PrimaryColor}"
VerticalOptions="Center"
HorizontalOptions="Start" Margin="10,0,0,0"/>
</StackLayout>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<controls:ExtendedViewCell IsEnabled="False">
<controls:ExtendedViewCell.View>
<Grid x:Name="GridWebcam">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Frame Grid.Column="1"
Grid.RowSpan="2"
CornerRadius="20"
BackgroundColor="{x:Static statics:Palette.PrimaryColor}"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
HasShadow="True"
Margin="5,10">
<StackLayout>
<Label Text="{Binding t_str_vid,Converter={StaticResource WebcamNameConverter}}"
FontSize="Medium"
TextColor="White"
FontAttributes="Bold"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
</Label>
<Label TextColor="White"
FontSize="Medium"
Text="{Binding direzione,Converter={StaticResource DirectionToStringConverter}}"/>
<StackLayout Orientation="Horizontal">
<ffimageloading:CachedImage LoadingPlaceholder="Rolling.gif"
DownsampleToViewSize="False"
VerticalOptions="FillAndExpand"
HorizontalOptions="StartAndExpand"
Source="{Binding image1}"/>
<iconize:IconButton Text="fas-play-circle"
FontSize="50"
HorizontalOptions="EndAndExpand"
VerticalOptions="EndAndExpand"
TextColor="White"
Command="{Binding BindingContext.OpenVideoWebcamCommand, Source={x:Reference WebcamList}}"
CommandParameter="{Binding .}"
BackgroundColor="Transparent"/>
</StackLayout>
</StackLayout>
</Frame>
</Grid>
</controls:ExtendedViewCell.View>
</controls:ExtendedViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
```
public class WebcamListViewModel : BaseViewModel
{
public ICommand OpenVideoWebcamCommand { set; get; }
private List<Webcam> _ListOfWebcam { get; set; }
public List<Webcam> ListOfWebcam
{
get { return _ListOfWebcam; }
set
{
_ListOfWebcam = value;
OnPropertyChanged();
}
}
private Task DownloadFramesTask;
CancellationTokenSource tokenSourceDownloadFrames = new CancellationTokenSource();
CancellationToken cancellationTokenDownloadFrames;
public WebcamListViewModel(INavigationService navigationService, IApiAutostradeManagerFactory apiAutostradeManagerFactory) : base(navigationService,apiAutostradeManagerFactory)
{
OpenVideoWebcamCommand = new Command<Webcam>(async (webcam) => {
await navigationService.NavigateAsync(Locator.WebcamVideoPopUpPage);
Messenger.Default.Send(new InfoWebcamVideoMessage(webcam.c_mpr, webcam.c_uuid, webcam.t_str_vid));
});
}
Well it could be related to this mysterious controls:ExtendedViewCell of yours :)
Also did you disable the ListView selection: <ListView ... SelectionMode="None" /> ?
As Roubachof said that I don't know if it is related to controls:ExtendedViewCell,please check if you have binding BindingContext, then you can take a look the following code:
<StackLayout>
<ListView x:Name="listview1" ItemsSource="{Binding persons}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Id}" />
<Label Text="{Binding name}" />
<Button
Command="{Binding BindingContext.command, Source={x:Reference listview1}}"
CommandParameter="{Binding Id}"
Text="Delete item" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
public partial class Page1 : ContentPage
{
public ObservableCollection<person> persons { get; set; }
public RelayCommand1 command { get; set; }
public Page1 ()
{
InitializeComponent ();
persons = new ObservableCollection<person>();
for(int i =0;i<20;i++)
{
person p = new person()
{
Id = i,
name = "cherry" + i
};
persons.Add(p);
command = new RelayCommand1(obj => method1((int)obj));
}
this.BindingContext = this;
}
public void method1(int Id)
{
persons.RemoveAt(Id);
//IEnumerable<person> list = persons.Where(x => x.Id == Id);
//foreach (person m in list)
//{
//}
}
}
public class person
{
public int Id { get; set; }
public string name { get; set; }
}
I have list view and its data source is ObservableCollection as given below.
ObservableCollection<empList_Model> diselectEmpModel = new ObservableCollection<empList_Model>();
ObservableCollection<empList_Model> selectEmpModel = new ObservableCollection<empList_Model>();
for (int i = 0; i < 10; i++)
selectEmpModel.Add (new empList_Model{ empName = "Employee " + i.ToString (), id = i.ToString () });
selectEmpModel.Add (new empList_Model{ empName = "Select All ", id = "All" });
listof_selectEmployee.ItemsSource = selectEmpModel;
public void itemSelectedof_selectEmployeeList(object sender, SelectedItemChangedEventArgs e)
{
var listview = sender as ListView;
var itemFor_AddingRemoving = listview.BindingContext as empList_Model;
selectEmpModel.Remove(itemFor_AddingRemoving);
listof_selectEmployee.ItemsSource = selectEmpModel;
diselectEmpModel.Add (itemFor_AddingRemoving);
listof_diselectEmployee.ItemsSource = diselectEmpModel;
}
public class empList_Model
{
public string empName{ get; set;}
public int Selected{ get; set;}
public string id{ get; set;}
}
Xaml :
<ListView Grid.Column="0" Grid.Row="1" x:Name="listof_selectEmployee" ItemSelected="itemSelectedof_selectEmployeeList" BackgroundColor="Gray" RowHeight="40" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20">
<Label Text="{Binding empName}" VerticalOptions="CenterAndExpand" TextColor="{x:Static color:ColorResources.listTextColor}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Grid.Column="1" Grid.Row="1" x:Name="listof_diselectEmployee" ItemSelected="itemSelectedof_diselectEmployeeList" BackgroundColor="Silver" RowHeight="40" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="20">
<Label Text="{Binding empName}" VerticalOptions="CenterAndExpand" TextColor="{x:Static color:ColorResources.listTextColor}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So, I have the two ListViews above and I want an item to be removed from the first list and added to the second ListView when a user clicks on any item of first ListView (itemSelectedof_selectEmployeeList() event). For some reason, when I tap on any item of ListView, nothing happens. Items are not removed from the first List nor are any added in second List. I don't know what I am missing.