use different data types in xaml properties - xaml

<Picker
Title="Select a Profile"
ItemsSource="{Binding ProfileManager.Profiles}"
ItemDisplayBinding="{Binding Name}"
SelectedItem="{Binding SelectedProfile, Mode=TwoWay}"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
SelectedIndex="1"
HeightRequest="200"
WidthRequest="325"
Margin="10"
BackgroundColor="{StaticResource Secondary}">
</Picker>
the itemSource property have x:DataType="ViewModels:ParametersViewModel" datatype but the ItemDisplayBinding have x:DataType="Models:Profile" datatype.
How can I define these datatypes seperatly?

Not sure If this answer works for you but you can define different data types inside same XAML file by clarifying Ancestor Type.
<ContentPage
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:Models="clr-namespace:Models"
xmlns:ViewModels="clr-namespace:ViewModels"
x:DataType="viewmodel:ParametersViewModel">
<Picker ItemsSource="{Binding ProfileManager.Profiles}"
ItemDisplayBinding="{Binding Source={RelativeSource AncestorType={x:Type Models:Profile}}, Path=Name}"/>
</ContentPage>
Once you set a DataType in the root (in this case ContentPage), all the bindings of its children will go to that datatype by default.

From document Populate a Picker with data using data binding, we could find that
A Picker can be also populated with data by using data binding to bind
its ItemsSource property to an IList collection.
<Picker Title="Select a monkey"
ItemsSource="{Binding Monkeys}"
ItemDisplayBinding="{Binding Name}" />
When binding to a list of objects, the Picker must be told which
property to display from each object. This is achieved by setting the
ItemDisplayBinding property to the required property from each object.
In the code examples above, the Picker is set to display each
Monkey.Name property value.
So, the ItemDisplayBinding property(Name) in your code above should be the required property from each object(Profile) in your ItemsSource(ProfileManager.Profiles).
In fact, we don't have to or need to specify what you call x:DataType for the Picker.
Note:
You can find the official sample here MonkeyAppPicker,though it is coded in xamarin , but the implementation on MAUI is almost the same.

Related

Binding current Item for Carousel of Content Views (held in Observable Collection)

I'm new to this community / Xamarin, and I've been stuck on this for a while so I need to reach out for help now.
I have a CarouselView of ContentViews and one of the view pages need to be validated so when the field is empty, I can revert back the correct carousel page using the Current Item binding BUT - although I am correctly retrieving the current item and the content view, the UI/binding isn't updating.
ContentViews is the ObservableCollection.
<Label Text="{Binding Source={x:Reference carouselView}, Path=CurrentItem,
StringFormat='Current item: {0}', FallbackValue='Current item:'}"/>
<Label Text="{Binding Source={x:Reference carouselView}, Path=Position,
StringFormat='Position: {0}'}"/>
<CarouselView
x:Name="carouselView"
IndicatorView="indicatorView"
ItemsSource="{Binding ContentViews}"
CurrentItem="{Binding CurrentItem}"
Position="{Binding Position}"
CurrentItemChanged="OnCurrentItemChanged"
PositionChanged="OnPositionChanged">
<CarouselView.ItemTemplate>
<DataTemplate>
<ContentView Content="{Binding .}" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
Do you have INotifyPropertyChanged implemented in you Binding Source?
check this , also check that the CarouselView Binding source is your desired class.

SelectedItem binding is not updating the ViewModel

I feel like I'm missing something obvious because this is so simple. Thanks in advance for the help. I'm struggling with binding the SelectedItem of a simple ListView in a Xamarin application. I'm testing on UWP and am using Prism's MVVM BindableBase base class. Here's what I'm experiencing:
The page loads and nothing in the list is selected.
I select an item in the list.
The setter of SelectedGrade is called with a value of null.
After that, selecting items does not cause the SelectedGrade setter to be called.
Here's the relevant XAML:
<ListView BackgroundColor="#7F7F7F"
CachingStrategy="RecycleElement"
IsPullToRefreshEnabled="True"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
ItemsSource="{Binding Grades, Mode=OneWay}"
SelectedItem="{Binding SelectedGrade, Mode=TwoWay}"
RefreshCommand="{Binding RefreshCommand}"
RowHeight="50">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand"
Orientation="Horizontal"
Padding="10">
<Label HorizontalOptions="FillAndExpand"
Text="{Binding Title}"
TextColor="#272832"/>
<Label HorizontalOptions="FillAndExpand"
Text="{Binding Score}"
TextColor="Aquamarine" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here's the ViewModel:
Grade _selectedGrade;
public Grade SelectedGrade
{
get { return _selectedGrade; }
set { SetProperty(ref _selectedGrade, value); } // this gets set to NULL the first time i select an item then never gets set again
}
Edit: I've also added an ItemSelected event listener in the code-behind and it is not being fired after the initial item is selected. The one time it is fired, the SelectedItemChangedEventArgs reveal that the ListView's SelectedItem is null. I can also see at this time that the ListView's ItemsSource has a collection of three items in it, as I would expect. I'm quite confused as to why the ListView thinks the SelectedItem is null and why it is not broadcasting when the selected item changes.
It looks like this was a bug in Xamarin. I upgraded from Xamarin.Forms 3.0.0.550146 to 3.1.0.637273 and now it works.
I have faced with the similar issue when List does not bind to view model with SelectedItem and Xamarin forms 5.0.0.2244.
It was resolved with setting default value of List property to new List() object instead null value in the view model before setting binding context . After that binding has became working.

{Binding .} in Xamarin

I saw this piece of code in an example of some Xamarin code:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding .}" TextColor="#66ffff" FontSize="Micro" HorizontalOptions="CenterAndExpand" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
What does Binding . mean? My guess from trying out the code is one character from the ItemsSource like in a regular expression? But I can't find this in the documentation.
The point (.) means that you bind the whole object/ model instead of a single property to the text property of that label. This is sometimes required, for example you need multiple aspects from your model in a converter.
In this code example above, it also could be that the item source for that listview is a list of strings. So there is no property to bind to the text property.

how to add multiple command buttons inside of xamarin listview using MVVM?

I am trying to create a listview where users can select the list item to view the store and also be able to click on the image to take them to the product detail.
How can I add a command in the ViewCell?
<ListView ItemsSource="{Binding myData}" x:Name="myListView" SelectedItem="{Binding SelectedStore}" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Label Text="{Binding Title}" />
<Image Source="product.png" >
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ItemTapCommand}" CommandParameter="Id" />
</Image.GestureRecognizers>
</Image>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
public ICommand ItemTapCommand => new Command(ShowSelectedProductAsync());
private async Task ShowSelectedProductAsync()
{
//take them to view the item detail
}
The problem is that you are attempting to bind to a command that is not located on the individual item within the ListView; the BindingContext on your Image is the individual items inside your myData collection.
With other frameworks, for example, Wpf, you would simply use the RelativeSource part of binding to tell the control to look for your command on the BindingContext of another control, however this isn't possible in Xamarin Forms (RelativeSource is not supported).
What you can do is the following, but it requires your UserControl to have an x:Name:
<TapGestureRecognizer Command="{Bindind Path=BindingContext.ItemTapCommand,
Source={x:Reference MyUserControl}}"
CommandParameter="{Binding Id}" />
What this says is to use the UserControl as the source for the binding, and the property is a nested property on that UserControl composed of BindingContext.ItemTapCommand.
As a bonus, I updated the code because I felt that you probably meant to bind the value of the Id property of each record as the command parameter, and not merely to send the string "Id" as the command parameter.

How to sort a Listview in a DataTemplate in XAML only?

I have a window with a TabControl that i've bind to a list of objec, I'll called MyItem :
<TabControl Name="MyTabPNL" Background="Gainsboro"
ItemsSource="{Binding MyItemList, ElementName=WatcherWindow}"
ContentTemplate="{StaticResource tabItemTemplate}">
</TabControl>
This MyItem class has an ObservableCollection, that I want to bind to a Listview, I'm doing this with a DataTemplate.
GOAL: I'd like to sort automatically this ObservableCollection in XAML. Usually i would use a CollectionViewSource, but i can't find a way to this... I've tried stuff like that:
<DataTemplate x:Key="tabItemTemplate">
<DataTemplate.Resources>
<CollectionViewSource x:Key='dayList' Source="{Binding MyDayList}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="MyDate" Direction="Descending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</DataTemplate.Resources>
<Grid >
<ListView ItemsSource="{Binding Source={StaticResource dayList}}" >
<ListView.View>
<GridView x:Name="gridvwDay" >
<GridViewColumn Header="MyDate"
CellTemplate="{StaticResource myCellTemplatePNLDate}"
HeaderContainerStyle="{StaticResource CustomHeaderStyleNeutral}"
Width="70" />
</GridView>
</ListView.View>
</ListView>
</Grid>
But everytime i've got the same error:
System.Windows.Data Error: 2 : Cannot
find governing FrameworkElement or
FrameworkContentElement for target
element.
BindingExpression:Path=MyDayList;
DataItem=null; target element is
'CollectionViewSource'
(HashCode=58368655); target property
is 'Source' (type 'Object')
I can't find a way to make a link between the dayList in the ListView ItemsSource, and the dayList in the CollectionRessource.
Do you guys have an idea?
FYI: pre sorting the ObservableCollection is not doable, because of the nature of the Class i'm using.
Have you tried simply,
<ListView ItemsSource="{StaticResource dayList}">
As per the doc: http://msdn.microsoft.com/en-us/library/ms750950.aspx
You don't need to bind when its just static on the page :)