I have a CustomCalendar element created by extending the ContentView and using this custom view inside another ContentPage. I tried to use Unfocused event to detect the outside click. But the problem is it is not triggering the event handler. Could you please suggest me to do the detecting of an element outside click in a better way.
I am using my custom view like this way in the page with an Unfocused EventToCommandBehavior
<views:CustomCalendar x:Name="cal">
<views:Calendar.Behaviors>
<prism:EventToCommandBehavior
EventName="Unfocused"
Command="{Binding UnfocusedCalandar}"/>
</views:Calendar.Behaviors>
</views:Calendar>
Unfocused event is raised whenever the VisualElement loses focus, and it only works for the element which is able to receive focus , unfortunately ContentView can't receive focus , so focused and Unfocused event would never trigger on ContentView .
Elements that can receive focus : Entry , Editor , Picker, and so on ...
As a temporary workaround , you could wrap the ContentView into StackLayout, set tap gesture both on ContentView and parenet layout , its own tap gesture will block parent view's gesture .
<StackLayout BackgroundColor="Red" >
<ContentView HeightRequest="100" WidthRequest="100" BackgroundColor="Blue" >
<ContentView.GestureRecognizers>
<TapGestureRecognizer Tapped="ContentViewTap"/>
</ContentView.GestureRecognizers>
</ContentView>
<CollectionView BackgroundColor="Gray" Focused="CollectionView_Focused" >
<CollectionView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Baboon</x:String>
<x:String>Capuchin Monkey</x:String>
<x:String>Blue Monkey</x:String>
<x:String>Squirrel Monkey</x:String>
<x:String>Golden Lion Tamarin</x:String>
<x:String>Howler Monkey</x:String>
<x:String>Japanese Macaque</x:String>
</x:Array>
</CollectionView.ItemsSource>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="dog.png"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding }"
FontAttributes="Bold" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding }"
FontAttributes="Italic"
VerticalOptions="End" />
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="StackLayoutTap" />
</Grid.GestureRecognizers>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="StackLayoutTap" />
</StackLayout.GestureRecognizers>
</StackLayout>
Related
I am working with a collectionview using GridItemsLayout orientation=“Vertical” Span=“2”.
When I click on a button that expands the lower part of my grid item. Currently only by using ItemSizingStrategy.MeasureAllItems I am able to get the lower part to expand. I was wondering if there is a way of controlling the item positioning on the image so the images always align and only the lower half expands evenly.
I am aware each item has its own layout, but this looks messy. I’ve read the documentation mention this type of sizing.
<ContentPage.Content>
<StackLayout>
<CollectionView x:Name="CollectionList"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding Shares}"
IsGrouped="True"
ItemSizingStrategy="MeasureAllItems">
<!--HEADER-->
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal"
Padding="5"
BackgroundColor="#f7f7fb">
<Label x:Name="labelname"
Text="{Binding GroupKey}"
/>
<Button Text=" More"
FontSize="16"
Clicked="OpenButton_Clicked"/>
</StackLayout>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<!--TEMPLATING-->
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<!--BODY-->
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="viewmodels:ShareViewModel">
<Grid Padding="5" Margin="1,0,1,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ImageButton x:Name="image"
Source="{Binding ImageLink}"
WidthRequest="150"
Clicked="FullImageView"
Grid.ColumnSpan="2"
Aspect="AspectFill"
Grid.Row="0"
Grid.Column="0"/>
<Label FontSize="16"
Text="{Binding Name}"
Grid.Row="1"
Grid.Column="0"/>
<Label x:Name="label_more"
Text="More"
Grid.Row="1"
Grid.Column="1"
HorizontalTextAlignment="End"/>
<Label
Text="{Binding CreateDate}"
Grid.Row="2"
Grid.Column="0"/>
<ImageButton IsVisible="{Binding TVNImageSet}"
Command="{Binding BindingContext.ToggleTVNCommand, Source={x:Reference Name=sharepage}}"
CommandParameter="{Binding .}"
Source="addresscard.png"
Grid.Row="2"
Grid.Column="1">
</ImageButton>
<!--Lower Section if the card is tapped (EXPAND)-->
<StackLayout
IsVisible="{Binding TVNVisible}"
Grid.Row="3"
Grid.ColumnSpan="2">
<StackLayout Orientation="Horizontal"
IsVisible="{Binding PhoneVisible}"
ClassId="{Binding Phone}">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"
NumberOfTapsRequired="1"
/>
</StackLayout.GestureRecognizers>
<Image Source="call.png"
WidthRequest="15"/>
<Label
FontSize="12"
Text="{Binding Phone}" />
</StackLayout>
<Label
FontSize="12"
Text="{Binding Address}"
IsVisible="{Binding AddressVisible}">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1" NumberOfTapsRequired="1"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
All BindingContext.ToggleTVNCommand does is set TVNVisible to true which shows the lower half the "expanding potion". I don't need to use collection view if there is an easier way fo displaying this data, but CollectionVView seemed like the best choice for the layout and item source I wanted.
After digging around GitHub forums on bugs and updates for Xamarin, someone mentioned to just work with SyncFusion's sfListview the membership is not that bad and my company is willing to pay for it if it makes working with Xamarin easier.
That wasn't the solution I was hoping for, but it works and their customer support is great.
below is the reference
https://help.syncfusion.com/xamarin/listview/working-with-sflistview
I have tried to make all the items in the itemtemplate into a single view as like in the below image, how to achieve this by using Xamarin CarouselView, i am using like this
carousel = new CarouselView();
carousel.BindingContext = this;
carousel.ItemTemplate = itemTemplate;
carousel.SetBinding(CarouselView.ItemsSourceProperty, new Binding(nameof(this.Items), mode: BindingMode.OneWay));
LinearItemsLayout linearItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal);
linearItemsLayout.SnapPointsAlignment = SnapPointsAlignment.Start;
linearItemsLayout.SnapPointsType = SnapPointsType.Mandatory;
carousel.ItemsLayout = linearItemsLayout;
this.Children.Add(carousel,0,1);
Expected UI
The easiest way of doing something like that would be to use the Horizontal CollectionView
CollectionView can display its items in a horizontal list by setting its ItemsLayout property to HorizontalList:
When you check the documents it gives a similar example
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
LineBreakMode="TailTruncation"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
Alternatively, this layout can also be accomplished by setting the ItemsLayout property to a LinearItemsLayout object, specifying the Horizontal ItemsLayoutOrientation enumeration member as the Orientation property value:
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
...
</CollectionView>
This results in a single row list, which grows horizontally as new items are added:
I'm building an app with a CollectionView, where I'd like the user to add an item to an ObservableCollection when the CollectionView is empty. Problem is: I cannot find out how to bind to the page's ViewModel.
This is a Xamarin.Forms/MvvmCross project
I tried setting the BindingContext, but I didn't succeed.
<CollectionView.EmptyView>
<Grid Padding="24,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="154" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="154" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<pan:PancakeView
CornerRadius="8"
WidthRequest="154"
HeightRequest="154"
IsClippedToBounds="True"
HorizontalOptions="FillAndExpand"
BackgroundColor="#FF252525"
VerticalOptions="FillAndExpand"
Elevation="2">
<pan:PancakeView.HasShadow>
<OnPlatform
x:TypeArguments="x:Boolean"
iOS="False"
Android="True" />
</pan:PancakeView.HasShadow>
<ImageButton
HorizontalOptions="FillAndExpand"
Padding="50"
VerticalOptions="FillAndExpand"
BackgroundColor="#FF252525"
BindingContext="{Binding .}"
Command="{Binding AddPlaylistCommand}"
Source="icon_plus" />
</pan:PancakeView>
</Grid>
</CollectionView.EmptyView>
Command binding doesn't work, I'd like my command to just bind to the page's Viewmodel.
Try this:
<ImageButton
HorizontalOptions="FillAndExpand"
Padding="50"
VerticalOptions="FillAndExpand"
BackgroundColor="#FF252525"
Command="{Binding Source={x:Reference Name=myPage}, Path=BindingContext.DataContext.AddPlaylistCommand}"
Source="icon_plus" />
Where myPage is is the Name of your ContentPage.
I want to implement a Carousel view swipe gesture recognizer left or right Swipes.
But ONLY tapped event can be recognized ,gesture events cannot be captured(not firing).
What i need is when user swipe left or right according to the swipe event i want to manage dot button opacity accordingly.
I saw some nuget packages already there to achieve this.I prefer not to use nuget packages.
I have tried the tapped event,tapped event is firing but not the gesture event
<CarouselView x:Name="CV" ItemsSource="{Binding People}" HeightRequest="200" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" Margin="10" >
<CarouselView.ItemsLayout>
<GridItemsLayout Orientation="Horizontal" SnapPointsAlignment="Center" SnapPointsType="Mandatory"/>
</CarouselView.ItemsLayout>
<CarouselView.ItemTemplate>
<DataTemplate>
<Frame BorderColor="LightGray" CornerRadius="3" HasShadow="False">
<Grid>
<Grid.GestureRecognizers>
<SwipeGestureRecognizer Direction="Left" Swiped="SwipeGestureRecognizer_OnSwiped" />
<SwipeGestureRecognizer Direction="Right" Swiped="SwipeGestureRecognizer_OnSwiped"/>
<SwipeGestureRecognizer Direction="Up" Swiped="SwipeGestureRecognizer_OnSwiped" />
<SwipeGestureRecognizer Direction="Down" Swiped="SwipeGestureRecognizer_OnSwiped"/>
</Grid.GestureRecognizers>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Source="person" VerticalOptions="Start"/>
<StackLayout Grid.Column="1" Grid.Row="1" HorizontalOptions="EndAndExpand" VerticalOptions="EndAndExpand">
<Label Text="{Binding}" FontSize="24" HorizontalOptions="EndAndExpand"/>
<Label Text="Company Address" HorizontalOptions="EndAndExpand"/>
<Label Text="City, State" HorizontalOptions="EndAndExpand"/>
</StackLayout>
</Grid>
</Frame>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
Yes,CarouselView have GestureRecognizers ,for example,
<CarouselView>
<CarouselView.GestureRecognizers>
<SwipeGestureRecognizer Swiped="OnSwiped" />
</CarouselView.GestureRecognizers>
</CarouselView>
method OnSwiped
private void OnSwiped(object sender, SwipedEventArgs e)
{
if (e.Direction == (e.Direction & SwipeDirection.Left))
{
}
}
I have a segment control where I'm displaying tabs. But I'm not able to edit the style of the tab in Xamarin Forms. This is the UI I want
This is how I want to display my tabs in the segment control. I'm able to change the tint color, background color, and text color but none of that will get me a tab in this style. This is my current UI
This is XAML code where I implemented the segment control
<controls:SegmentedControl BackgroundColor="White" SelectedTextColor="Black" TintColor="#FFA500" x:Name="SegControl" ValueChanged="Handle_ValueChanged">
<controls:SegmentedControl.Children>
<controls:SegmentedControlOption Text="VENDOR NAME" />
<controls:SegmentedControlOption Text="PRODUCT/SERVICE" />
</controls:SegmentedControl.Children>
</controls:SegmentedControl>
<StackLayout x:Name="SegContent" />
</StackLayout>
<StackLayout Margin="0,30,0,0">
<StackLayout AbsoluteLayout.LayoutBounds=".20,1,1,.1" AbsoluteLayout.LayoutFlags="All" BackgroundColor="White" HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckNear">
<Image Margin="0,10,0,10" x:Name="imgNear" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Near" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckSearch">
<Image Margin="0,10,0,10" x:Name="imgSearch" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Search" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckCart">
<Image Margin="0,10,0,10" x:Name="imgCart" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Cart" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
<StackLayout Style="{StaticResource ButtonNavigationBarStackLayoutStyle}" x:Name="stckAccount">
<Image Margin="0,10,0,10" x:Name="imgAccount" Style="{StaticResource ButtonNavigationBarImageStyle}" />
<Label Text="Account" Style="{StaticResource ButtonNavigationBarLabelStyle}"></Label>
</StackLayout>
</StackLayout>
I'm not using any custom renderer for this segment control. Do I have to use a custom renderer for implementing the required UI? If yes how? Any suggestions?
SegmentedControl is not a built in Xamarin.Forms control. There are a few libraries that offer a SegmentedControl, so it would help to know which one you are using.
That said, the library author who created that SegmentedControl also made the platform renderers and so the different look on iOS vs Android is a result of that.
You can, of course, create your own custom renderer, but then why use the library?
Easier to me would be to make a control using Xamarin Forms, for instance you can use a grid that has a first row of two labels ( or Buttons) and a second row of 2 BoxViews that can act as the underline (very short height). Then just add TapGestureRecognizers to each Label (or just use a Buttons and style as needed).
Here's an example using Buttons and BoxViews:
XAML:
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button x:Name="vBtn"
Text="VENDOR NAME" Clicked="Handle_Clicked"
TextColor="Black"
BackgroundColor="Transparent"
BorderColor="Transparent"
Grid.Row="0"
Grid.Column="0"/>
<Button x:Name="pBtn"
Text="PRODUCT/SERVICE" Clicked="Handle_Clicked"
TextColor="Black"
BackgroundColor="Transparent"
BorderColor="Transparent"
Grid.Row="0"
Grid.Column="1" />
<BoxView x:Name="vBox"
Color="#FFA500" HeightRequest="5"
Grid.Row="1"
Grid.Column="0"/>
<BoxView x:Name="pBox"
Color="Silver" HeightRequest="5"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
Code behind:
void Handle_Clicked(object sender, System.EventArgs e)
{
Button btn = sender as Button;
if (btn.Text == "PRODUCT/SERVICE")
{
vBox.Color = Color.Silver;
pBox.Color = Color.FromHex("#FFA500");
// Do anything else you need to do when the PRODUCT/SERVICE is tapped
}
else
{
vBox.Color = Color.FromHex("#FFA500");
pBox.Color = Color.Silver;
// Do anything else you need to do when the VENDOR NAME is tapped
}
}
No library or custom renderer needed.