How to access element in Xamarin Forms Expander by name? - xaml

I'm using the xamarin extended toolkit to show some Expanders in my application. What I'm trying to do is access an element in my Expander.ContentTemplate by setting x:Name. However when I try to access the element in my code-behind it doesn't find anything. What is the correct way to access any Label/Entry/Picker by name so I can manipulate it in the code-behind?
<xct:Expander Margin="0,0,0,20">
<xct:Expander.Header>
<Grid>
<Label FontAttributes="Bold" Text="Bookings" FontSize="Medium"/>
<Image Source="expand.png" HorizontalOptions="End"
VerticalOptions="Start">
<Image.Triggers>
<DataTrigger TargetType="Image"
Binding="{Binding Source={RelativeSource AncestorType={x:Type xct:Expander}}, Path=IsExpanded}"
Value="True">
<Setter Property="Source"
Value="collapse.png" />
</DataTrigger>
</Image.Triggers>
</Image>
</Grid>
</xct:Expander.Header>
<xct:Expander.ContentTemplate>
<DataTemplate>
<StackLayout Margin="0,10">
<Label x:Name="LabelDefaultPickup" FontAttributes="Bold" Text="Default Pickup location"/>
<Picker x:Name="PickupPicker" ItemsSource="{Binding ActivePickupList, Source={ x:Reference profilePage}}" ItemDisplayBinding="{Binding naam}" SelectedIndexChanged="PickupPicker_SelectedIndexChanged"/>
<Label x:Name="LabelDefaultPickupTime" FontAttributes="Bold" Text="Default Pickup time"/>
<Entry x:Name="DefaultPickupTime" Placeholder="pickup time" Text="{Binding Path=uurHeen}"/>
<Label x:Name="LabelDefaultDeparture" FontAttributes="Bold" Text="Default work location"/>
<Entry x:Name="DefaultDeparture" Placeholder="Location id" Text="{Binding Path=corp_id}"/>
<Label x:Name="LabelDefaultDepartureTime" FontAttributes="Bold" Text="Default Departure time"/>
<Entry x:Name="DefaultDepartureTime" Placeholder="Location id" Text="{Binding Path=uurTerug}"/>
</StackLayout>
</DataTemplate>
</xct:Expander.ContentTemplate>
</xct:Expander>

After reading the docs again, I removed the ContentTemplate tags (content is only rendered when the expander is tapped for the first time) after this change I could access an element like this:
var picker = BookingExpander.FindByName("PickupPicker") as Picker;
if (picker != null)
{
//do whatever you want
}

Related

How do I write xaml to bind (in MAUI) to a field other than the one specified in ItemsSource of the CollectionView?

I have this (probably naïve question):
I have this xaml:
<CollectionView
ItemsSource="{Binding Receipts}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Receipt">
<Grid Padding="1, 1, 1, 1">
<Frame Style="{StaticResource CardView}">
<Frame.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:ER_Expense_Receipts_View_VM}}, Path=GoToReceiptDetailsCommand}"
CommandParameter="{Binding .}" />
</Frame.GestureRecognizers>
<Grid RowDefinitions="Auto, *" ColumnDefinitions="310, 20" RowSpacing="10">
<Image
x:Name="imgReceipt"
Aspect="AspectFit"
Margin="0"
Grid.ColumnSpan="2"
Source="{Binding ContentsThumbnail, Mode=OneWay, Converter={StaticResource ByteArrayToImageSourceConverter}}"
WidthRequest="300" />
<Label
Grid.Row="1"
FontSize="12"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
VerticalOptions="Start"
VerticalTextAlignment="Center"
HeightRequest="30"
Text="{Binding Description}">
</Label>
<ImageButton
x:Name="cmdDelete"
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:ER_Expense_Receipts_View_VM}}, Path=DeleteReceiptCommand}"
CommandParameter="{Binding ID}"
Grid.Row="1"
Grid.Column="1"
Source="delete2.svg"
HeightRequest="20"
WidthRequest="40">
<ImageButton.Triggers>
<DataTrigger TargetType="ImageButton" Binding="{Binding ExpenseReport.Status}" Value="{x:Static res:AppRes.StatusSent}">
<Setter Property="IsEnabled" Value="False" />
<Setter Property="TextColor" Value="Gray" />
</DataTrigger>
</ImageButton.Triggers>
</ImageButton>
</Grid>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Receipts is a collection of Receipt objects in my "ER_Expense_Receipts_View_VM" model:
[ObservableProperty]
private Receipt receipt;
public ObservableCollection<Receipt> Receipts { get; } = new();
Also in my model I have this property
[ObservableProperty]
private Expense expense;
What I need to do here is to bind the "cmdDelete" ImageButton's property IsEnabled to the Status field of the ExpenseReport object in the model. See below. Alas, I get the message "Member not found in data context 'Receipt'".
So, please, what I am doing wrong here ? What's the correct syntax to bind that IsEnabled property to some field in the model other than from the Receipt objects ?
Thank you very much,
Alex

How to dynamically adjust positioning of a VerticalStackLayout inside a Grid?

I'm creating an app using MAUI and I'm trying to make it so an ImageButton and SearchBar nested in a VerticalStackLayout move positioning based on the dynamically created CollectionView.
This is the code for the UI:
<Grid>
<FlexLayout VerticalOptions="Center" HorizontalOptions="Center">
<StackLayout>
<CollectionView x:Name="taskList">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Task">
<VerticalStackLayout Margin="15">
<Entry Text="{Binding name}" IsReadOnly="True" />
<Entry Text="{Binding departmentsString}" IsReadOnly="True"/>
<HorizontalStackLayout>
<Entry Text="{Binding status}" IsReadOnly="True"/>
<Entry Text="{Binding deadline}" IsReadOnly="True" />
<Entry Text="{Binding author.fullName}" IsReadOnly="True"/>
</HorizontalStackLayout>
<Entry Text="{Binding description}" IsReadOnly="True" />
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
<VerticalStackLayout Margin="15">
<Entry Placeholder="Name" x:Name="nameTxt"/>
<Entry Placeholder="Department" x:Name="departTxt"/>
<HorizontalStackLayout>
<inputs:SfComboBox x:Name="statusTxt" Placeholder="Status" BackgroundColor="Black" TextColor="Green" DropDownIconColor="Green"/>
<Entry Placeholder="deadline" x:Name="deadlineTxt"/>
<Entry Placeholder="Author" x:Name="authorTxt"/>
</HorizontalStackLayout>
<Entry Placeholder="Description" x:Name="descTxt"/>
</VerticalStackLayout>
</FlexLayout>
<VerticalStackLayout VerticalOptions="Center" >
<SearchBar Placeholder="Search" x:Name="searchBar" TextChanged="searchBar_TextChanged" MaxLength="30" MaximumWidthRequest="200"/>
<ImageButton Aspect="AspectFill" x:Name="addBtn" Source="plus.png" BackgroundColor="Black" Clicked="addBtn_Clicked" HeightRequest="64" WidthRequest="64"/>
</VerticalStackLayout>
</Grid>
I have tried every different type of Layout but nothing works.
What should I do?

Trigger IsVisible true- false of label on radio button checked- Uncheck in xaml

I am trying to show/hide a label using Trigger on RadioButton check/uncheck but I am getting the error. I can also do it in c# code by inotifypropertychanged but i want to use Triggers and this is my first time. I am not able to understand this error.
<StackLayout Orientation="Vertical" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Padding="10">
<Frame HasShadow="False" Margin="10,20" CornerRadius="5" BorderColor="{StaticResource BorderColor}" BackgroundColor="#F7F7F7">
<Grid HorizontalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<RadioButton Content="English" x:Name="rdbEnglish" HorizontalOptions="FillAndExpand" BackgroundColor="Transparent"
CornerRadius="10" BorderWidth="2" Margin="2"
Grid.Column="0" Grid.Row="0" IsChecked="{Binding IsCheckedEnglish,Mode=TwoWay}" >
</RadioButton>
<RadioButton Content="hindi" x:Name="rdbHindi" HorizontalOptions="FillAndExpand"
BackgroundColor="Transparent"
CornerRadius="10" BorderWidth="2" IsChecked="{Binding IsCheckedHindi,Mode=TwoWay}"
Margin="2" Grid.Column="1" Grid.Row="0" />
</Grid>
</Frame>
<StackLayout Orientation="Vertical" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Padding="10">
<Label x:Name="lblrdbEnglish" Text="Note : Menu iteam changes will be updated next time"
Margin="2,-10,2,5" TextColor="Red" IsVisible="false" FontAttributes="Italic" >
<Label.Triggers>
<DataTrigger TargetType="RadioButton"
Binding="{Binding Source={x:Reference rdbEnglish},Path=IsChecked}" Value="True" >
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
</Label.Triggers>
</Label>
</StackLayout>
</StackLayout>
Error
System.InvalidOperationException: 'bindable not an instance of AssociatedType'
The TargetType should be of type Label and not RadioButton.
From triggers docs:
TargetType - the control type that the trigger applies to.
...
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding Source={x:Reference rdbEnglish},
Path=IsChecked}" Value="True">
<Setter Property="IsVisible" Value="True" />
</DataTrigger>
</Label.Triggers>

Xamarin Forms Frame in Android

I have four frames, I want to enter in that number. When running on Windows, the numbers are fully visible, but when I run on Android, numbers are not visible or half appear.
I do not want to change outlines so that they get out of shape
And change their appearance
I'm beginner in xamarin
Please advise me to display the numbers correctly while running on Android without changing the appearance of my frames.
XAML:
<Style TargetType="Frame" >
<Setter Property="BackgroundColor" Value="White"/>
<Setter Property="CornerRadius" Value="15"/>
<Setter Property="HeightRequest" Value="30"/>
<Setter Property="BorderColor" Value="Blue"/>
<Setter Property="Margin" Value="3"/>
</Style>
</ContentPage.Resources>
<StackLayout BackgroundColor="White" Orientation="Vertical" >
<Image Source="d.png" WidthRequest="60" HeightRequest="60" Margin="0,5,0,5"/>
<BoxView WidthRequest="40" HeightRequest="60" BackgroundColor="Pink" HorizontalOptions="Center"/>
<Label Text="کد ارسال شده را اینجا وارد کنید" TextColor="Black" FontSize="15" HorizontalOptions="Center" Margin="0,5,0,0"
VerticalOptions="Center"/>
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" Spacing="10" BackgroundColor="White">
<Frame WidthRequest="80" x:Name="frame1" >
<Entry Keyboard="Numeric" TextColor="Black" FontSize="20" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" MaxLength="1"
HorizontalTextAlignment="Center" Focused="Entry_Focused" Unfocused="Entry_unFocused" />
</Frame>
<Frame WidthRequest="80" x:Name="frame2" >
<Entry Keyboard="Numeric" TextColor="Black" FontSize="20" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
HorizontalTextAlignment="Center" MaxLength="1" Focused="Entry_Focused1" Unfocused="Entry_unFocused1" />
</Frame>
<Frame WidthRequest="80" x:Name="frame3" >
<Entry Keyboard="Numeric" TextColor="Black" FontSize="20" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
HorizontalTextAlignment="Center" Focused="Entry_Focused2" Unfocused="Entry_unFocused2" MaxLength="1" />
</Frame>
<Frame WidthRequest="80" x:Name="frame4"
>
<Entry Keyboard="Numeric" FontSize="20" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
MaxLength="1" HorizontalTextAlignment="Center" Focused="Entry_Focused3" Unfocused="Entry_unFocused3" />
</Frame>
</StackLayout>
<Button x:Name="Button" Text="تایید" TextColor="White" BackgroundColor="Green" HorizontalOptions="Center"
VerticalOptions="End" WidthRequest="340" HeightRequest="50" CornerRadius="5" Margin="0,10,0,10"/>
</StackLayout>
You can set the specific heightrequest for android in the Frame
Here is running screenshot in android.
Here is code.
<Frame x:Name="frame1" WidthRequest="80" >
<Entry Keyboard="Numeric" TextColor="Black" FontSize="20" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" MaxLength="1"
HorizontalTextAlignment="Center" Focused="Entry_Focused" Unfocused="Entry_Unfocused" >
</Entry>
<Frame.HeightRequest>
<OnPlatform Android="50" ></OnPlatform>
</Frame.HeightRequest>
</Frame>

Bind BackgroundColor of a view inside DataTemplate Xamarin.Forms

I have a list view with a DataTemplate and inside it I have a StackLayout that I need set its background but the color of it is inside a variable...When I programmatically set the background of an object using this variable color it works, but when I try to use "binding" in xaml it doesn't work and I can't get this stack programmatically because it's inside a data template...
I really need your answer..
Some help?
<ListView.ItemTemplate>
<DataTemplate>
<!--<DataTemplate.Triggers>
<DataTrigger Binding="{Binding fundoColor}" Value="4">
<Setter TargetName="produtos_stack_color" Property="Background" Value="LawnGreen" />
</DataTrigger>
</DataTemplate.Triggers>-->
<ViewCell>
<StackLayout x:Name="produtos_stack_color" BackgroundColor="{Binding fundoColor}" VerticalOptions="FillAndExpand" Margin="10,10,10,10">
<StackLayout Orientation="Horizontal" Padding="10,10,10,10" BackgroundColor="Black" HorizontalOptions="FillAndExpand">
<Image Source="{Binding imagem}" HeightRequest="80" HorizontalOptions="CenterAndExpand" WidthRequest="160" Aspect="Fill"/>
<StackLayout Orientation="Horizontal" BackgroundColor="Green" VerticalOptions="Center" HorizontalOptions="CenterAndExpand">
<Label Style="{StaticResource labelsfont}" Text="R$" FontSize="Medium" TextColor="White"/>
<Label Style="{StaticResource labelsfont}" Text="{Binding valor}" FontAttributes="Bold" FontSize="Large" TextColor="White"/>
</StackLayout>
</StackLayout>
<StackLayout Margin="0,0,0,10">
<Label Text="{Binding nome}" Style="{StaticResource labelsfont}" FontAttributes="Bold" FontSize="Medium" TextColor="White" VerticalOptions="StartAndExpand" HorizontalOptions="Center"/>
<ContentView BackgroundColor="Chartreuse" HorizontalOptions="FillAndExpand">
<Label Style="{StaticResource labelsfont}" Text="{Binding observacao}" TextColor="White" Margin="10,10,10,10" HorizontalOptions="Center" />
</ContentView>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
I heard about triggers...but I really don't know how it works exactly...
I need produtos_stack_color receive the color
My global variable in code behind...It is setted just in construct of my class
InitializeComponent();
fundoColor = Color.FromHex(this.categEscolhida.corFundo);
You can only bind with properties - so you will have to create a property in code-behind class.
public Color FundoColor { get { return fundoColor; } }
Secondly, in order to refer this property in XAML - you can use Reference extension, and specify parent as Source. For e.g.:
<StackLayout x:Name="produtos_stack_color"
BackgroundColor="{Binding FundoColor, Source={x:Reference ParentHost}}" ..>
And, make sure to set x:Name attribute in root node of your XAML. For e.g:
<ContentPage x:Name="ParentHost" .. />