I have simple problem with binding color. When I try binding BorderHexColor, I get following error:
No property, bindable property, or event found for 'BorderHexColor', or mismatching type between value and property.
When:
<ffTransformations:RoundedTransformation Radius="240"
BorderHexColor="#fc0303"
BorderSize="10"/>
The code without binding BorderHexColor works well.
My code:
<CollectionView x:Name="collectionStories"
ItemsSource="{Binding .}"
HeightRequest="75"
HorizontalScrollBarVisibility="Never"
ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Margin="5,0,5,0">
<ff:CachedImage Source="{Binding instagramModel.ProfilePicture}"
WidthRequest="50"
HeightRequest="50"
VerticalOptions="Center"
HorizontalOptions="Center">
<ff:CachedImage.Transformations>
<ffTransformations:RoundedTransformation Radius="240"
BorderHexColor="{Binding HexColor}"
BorderSize="10"/>
</ff:CachedImage.Transformations>
<ff:CachedImage.GestureRecognizers>
<TapGestureRecognizer Tapped="InstaStory_Tapped"/>
</ff:CachedImage.GestureRecognizers>
</ff:CachedImage>
<Label Text="{Binding instagramModel.Username}"
TextColor="Gray"
FontSize="Small"
VerticalOptions="Center"
HorizontalOptions="Center"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
My class:
public class InstaStories
{
public InstagramModel instagramModel { get; set; }
public Post Post { get; set; }
public bool IsSeen { get; set; }
public string HexColor
{
get
{
if (!IsSeen)
{
return "#fc0303";
}
else
{
return "#28fc03";
}
}
}
}
I beleive you will need a value converter. When XAML is compiled, the system automatically converts the hex string into a color. But it cannot do this when you bind to a string. Alternatively, you can bind to a color and convert in code behind before you provide the color value.
Related
This sounds like a mouthful but I have a BindableLayout.ItemTemplateSelector that is located inside of a DataTemplate. The problem is I can not pass a property of the DataTemplate's ItemSource for some reason.
In section 'Data Template', of 'The Code' below, I am trying to access properties inside of ItemSource="{Binding CarouselItems}" from within <controls:ThoughtEntryDataTemplateSelector>. However, I can't access anything inside of there except for StaticResource's.
I'd like to pass a property from CarouselItems into it
The Code
Data Template
<cards:CarouselView
x:Name="ThoughtCarouselViewer"
IndicatorView="indicatorView"
IsCyclical="False"
ItemsSource="{Binding CarouselItems}">
<cards:CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label
x:Name="Title"
FontAttributes="Bold"
Text="{Binding Header}"
TextColor="{StaticResource TextColor}" />
<rv:MaterialFrame
Padding="5"
LightThemeBackgroundColor="#F1F1F1"
Style="{StaticResource CardView}">
<StackLayout BindableLayout.ItemsSource="{Binding Source={RelativeSource AncestorType={x:Type local:ThoughtRecordViewModel}}, Path=ThoughtEntryContainers}" Orientation="Vertical">
<BindableLayout.ItemTemplateSelector>
<controls:ThoughtEntryDataTemplateSelector
ChallengingThought="{StaticResource ChallengingThought}"
Distortions="{StaticResource Distortions}"
NegativeThought="{StaticResource NegativeThought}"
ThoughtType="{Binding ThoughtEntryType}" /> <============================== What I am trying to access
</BindableLayout.ItemTemplateSelector>
</StackLayout>
</rv:MaterialFrame>
</StackLayout>
</DataTemplate>
</cards:CarouselView.ItemTemplate>
</cards:CarouselView>
DataTemplateSelector
public class ThoughtEntryDataTemplateSelector : DataTemplateSelector
{
public DataTemplate NegativeThought { get; set; }
public DataTemplate Distortions { get; set; }
public DataTemplate ChallengingThought { get; set; }
public ThoughtEntryType ThoughtType { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
DataTemplate dataTemplate;
if(ThoughtType == ThoughtEntryType.NegativeThought)
{
dataTemplate = NegativeThought;
} else if(ThoughtType == ThoughtEntryType.Distortion)
{
dataTemplate = Distortions;
} else
{
dataTemplate = ChallengingThought;
}
return dataTemplate;
}
}
Carousel Items
public class ThoughtEntryCarouselItems
{
private string header;
public string Header
{
get => header;
set => header = value;
}
private ThoughtEntryType thoughtEntryType;
public ThoughtEntryType ThoughtEntryType
{
get => thoughtEntryType;
set => thoughtEntryType = value;
}
}
According to Creating a Xamarin.Forms DataTemplateSelector, I suggest you can choose a DataTemplate for CarouselView, not for StackLayout, then you can get current item ThoughtEntryType in OnSelectTemplate method, please see my code.
<ContentPage.Resources>
<DataTemplate x:Key="ChallengingThought">
<StackLayout >
<Label FontAttributes="Bold" Text="{Binding Header}" />
<Frame CornerRadius="30" BorderColor="Black" BackgroundColor="AliceBlue">
<StackLayout BindableLayout.ItemsSource="{Binding EntryContainers}" Orientation="Vertical">
<Label Text="{Binding .}" />
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
<DataTemplate x:Key="NegativeThought" >
<StackLayout>
<Label FontAttributes="Bold" Text="{Binding Header}" />
<Frame CornerRadius="30" BorderColor="Black" BackgroundColor="DarkGray">
<StackLayout BindableLayout.ItemsSource="{Binding EntryContainers}" Orientation="Vertical">
<Label Text="{Binding .}" />
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
<DataTemplate x:Key="Distortions">
<StackLayout >
<Label FontAttributes="Bold" Text="{Binding Header}" />
<Frame CornerRadius="30" BorderColor="Black" BackgroundColor="YellowGreen">
<StackLayout BindableLayout.ItemsSource="{Binding EntryContainers}" Orientation="Vertical">
<Label Text="{Binding .}" />
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
<local:ThoughtEntryDataTemplateSelector x:Key="EntryDataTemplateSelector"
ChallengingThought="{StaticResource ChallengingThought}"
Distortions="{StaticResource Distortions}"
NegativeThought="{StaticResource NegativeThought}"/>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<CarouselView
x:Name="ThoughtCarouselViewer"
ItemsSource="{Binding CarouselItems}" ItemTemplate="{StaticResource EntryDataTemplateSelector}">
</CarouselView>
</StackLayout>
</ContentPage.Content>
public partial class Page24 : ContentPage
{
public Page24()
{
InitializeComponent();
this.BindingContext = new ThoughtRecordViewModel();
}
}
public class ThoughtRecordViewModel
{
public ObservableCollection<ThoughtEntryCarouselItems> CarouselItems { get; set; }
public ThoughtRecordViewModel()
{
CarouselItems = new ObservableCollection<ThoughtEntryCarouselItems>()
{
new ThoughtEntryCarouselItems(){Header="header 1",EntryType=ThoughtEntryType.ChallengingThought,EntryContainers=new ObservableCollection<string>(){"1","2","3"}},
new ThoughtEntryCarouselItems(){Header="header 2",EntryType=ThoughtEntryType.Distortions,EntryContainers=new ObservableCollection<string>(){"a","b","c"}},
new ThoughtEntryCarouselItems(){Header="header 3",EntryType=ThoughtEntryType.NegativeThought,EntryContainers=new ObservableCollection<string>(){"11","22","33"}},
new ThoughtEntryCarouselItems(){Header="header 4",EntryType=ThoughtEntryType.ChallengingThought,EntryContainers=new ObservableCollection<string>(){"112","2222","3333"}},
};
}
}
public class ThoughtEntryCarouselItems
{
private string header;
public string Header
{
get => header;
set => header = value;
}
private ThoughtEntryType _EntryType;
public ThoughtEntryType EntryType
{
get => _EntryType;
set => _EntryType = value;
}
public ObservableCollection<string> EntryContainers { get; set; }
}
public enum ThoughtEntryType
{
NegativeThought, Distortions, ChallengingThought
}
public class ThoughtEntryDataTemplateSelector : DataTemplateSelector
{
public DataTemplate NegativeThought { get; set; }
public DataTemplate Distortions { get; set; }
public DataTemplate ChallengingThought { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
DataTemplate dataTemplate=null;
ThoughtEntryCarouselItems carouseitem = (ThoughtEntryCarouselItems)item;
if (carouseitem.EntryType == ThoughtEntryType.NegativeThought)
{
dataTemplate = NegativeThought;
}
else if (carouseitem.EntryType == ThoughtEntryType.Distortions)
{
dataTemplate = Distortions;
}
else if(carouseitem.EntryType == ThoughtEntryType.ChallengingThought)
{
dataTemplate = ChallengingThought;
}
return dataTemplate;
}
}
Im trying to bind my ListView to an observableCollection on my ViewModel. The other bindings on the same class are working but i dont see any data where my list is supposed to be.
Ive tried setting the rows uneven, instantiating a separate Collection, and using breakpoints to confirm there is data.
Here is the xaml code:
<StackLayout Spacing="10" Padding="7" Grid.Row="1" Grid.Column="0">
<Label Text="Name:" FontSize="Medium"/>
<Label Text="{Binding order.Name}" FontSize="Small"/>
<Label Text="Price:" FontSize="Medium"/>
<Label Text="{Binding order.Price}" FontSize="Small"/>
</StackLayout>
<ListView ItemsSource="{Binding order.foodItems}" Grid.Row="0" Grid.Column="0" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10" Orientation="Horizontal" HorizontalOptions="Fill">
<Label Text="{Binding Name}" FontSize="Medium"/>
<Label Text="{Binding Quantity}" FontSize="Medium" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is my ViewModel
Order _order;
public Order order
{
get { return _order; }
set { SetProperty<Order>(ref _order, value); }
}
public OrderDetailViewModel(Order value)
{
order = value;
}
The order class:
public class Order
{
public string Name { get; set; }
public ObservableCollection<IFoodItems> foodItems;
public double Price { get; set; }
public Order(string name)
{
Name = name;
foodItems = new ObservableCollection<IFoodItems>();
}
public void SetPrice(double value)
{
Price = value;
}
public void AddItem(IFoodItems food)
{
foodItems.Add(food);
}
}
I have a list of Programs and I binding it to Xamarin forms ListView
public class Program
{
public string Text { get; set; }
public string Color { set; get; }
public LayoutAlignment LangDirection { set; get; }
}
Text and Color works fine but LangDirection of type LayoutAlignment not working!
<ListView x:Name="ItemsListView"
ItemsSource="{Binding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label TextColor="{Binding Color}"
Text="{Binding Text}"
FontSize="16"
HorizontalOptions="{Binding LangDirection}"
/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And no error occur
I am using Prism in my Xamarin forms app, I have a ListView where each Listitem has 2 images, an edit image and delete image.
I have usedTapGesturesRecognizers on these 2 images, and binded _DelegateCommands for these TapGestureRecognizers. However these DelegateCommands do not get called.
Thanks in advance
This is my XAML code
<ListView x:Name="lstAddress" HasUnevenRows="True" SeparatorVisibility="None" ItemsSource="{Binding ListItems}" CachingStrategy="RecycleElement" >
<ListView.Behaviors>
<b:EventToCommandBehavior EventName="ItemTapped"
Command="{Binding ListItemSelectCommand}" EventArgsParameterPath="Item"/>
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Description}" FontSize="15" TextColor="#959595">
</Label>
<Image Source="Edit.png" HeightRequest="50" WidthRequest="50" IsVisible="{Binding ShowEdit}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command ="{Binding EditAddressCommand}"></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>
<Image Source="Delete.png" ClassId="{Binding ListID}" HeightRequest="30" WidthRequest="30" IsVisible="{Binding ShowIcon}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command ="{Binding DeleteAddressCommand}"></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In my ViewModel:
public class AddressBookViewModel : BindableBase
{
INavigationService _navigationService;
public DelegateCommand EditAddressCommand { get; set; }
public DelegateCommand DeleteAddressCommand { get; set; }
public ObservableCollection<ListModel> ListItems {get;set;} = new ObservableCollection<ListModel>();
public DelegateCommand<ListModel> ListItemSelectCommand { get; set; }
public MyZypListsViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
EditAddressCommand = new DelegateCommand(EditAddress);
DeleteAddressCommand = new DelegateCommand(DeleteAddress);
ListItemSelectCommand = new DelegateCommand<ListModel>(ListItemSelected);
}
private void EditAddress()
{
//Edit listitem
}
private void DeleteAddress()
{
//Delete listitem
}
}
For each item on your list, your BindingContext is not the same as the ListView's BindingContext. Locally your BindingContext is the item itself, this is why you can obtain the 'Description' property, for example. Xamarin is searching for an ICommand called EditAddressCommand in your item, not in your view model.
You can make a Cross Binding reference if you want... Just replace your commands at item template to this way:
Command ="{Binding BindingContext.EditAddressCommand, Source={x:Reference lstAddress}"
It may work.
At the moment I am programming an application based on Xamarin. My goal is to toggle the switch based on values in a table. Problem is, Xamarin is not noticing my x:Name toggle_true connected to my switch.
Here is my script in xaml:
<ListView x:Name="defineBuildingItems">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<StackLayout Orientation="Vertical">
<Label Text="{Binding defineDescription}" x:Name="Current_item"/>
</StackLayout>
<Switch BindingContext ="{Binding defineId}" HorizontalOptions="EndAndExpand"
Toggled="Handle_Toggled" x:Name="toggled_true"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is my c# code in code behind:
var currentQuestions = _define.Where(s => DefineId.Contains(s.defineId));
//Remember what building was defined like last time defineBuilding was proceeded.
foreach (DefineTable i in currentQuestions)
{
toggled_true.IsToggled = true;
}
defineBuildingItems.ItemsSource = posts;
base.OnAppearing();
}
Notice how it recognizes the x:Name defineBuildingItems. The error i get on toggled_true is: The name toggled_true does not exist in the current namespace. Is there something I am doing wrong or missing?
Access to control by name inside datatemplate not working. You must using binding. This is simply example:
Model:
public class Data
{
public bool IsToggled {get;set;}
....
}
Code behind:
public YourPage
{
BindingContext = this;
}
....
private List<Data> _items;
public List<Data> Items
{
get { return _items;}
set
{
_items = value;
OnPropertyChanged();
}
}
Your xaml:
<ListView x:Name="defineBuildingItems" ItemSources={Binding Items}>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<StackLayout Orientation="Vertical">
<Label Text="{Binding defineDescription}" />
</StackLayout>
<Switch IsToggled ="{Binding IsToggled, Mode =TwoWay}" HorizontalOptions="EndAndExpand" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>