I am new to xamarin.forms
I have a listview that is filled from backend c# code.
I have one label and one image defined in it. And I have given x:Name property in XAML.
Now, my question is I want to access those two labels in backend c# code. But both the labels are not accessible because they are in listview. If I put label outside listview, I can access it in the code.
Please avoid syntax errors. My code works fine. I want to access these elements so that I can change style for phone and tablet.
My XAML code :
// ...
<ListView x:Name="DentistList">
<Listview.ItemTemplate>
<DataTemplate>
<ViewCell>
<Image Source="{Binding ImagePath}" x:Name="DoctorImage"/>
<Label Text="{Binding Name}" x:Name="DoctorName" />
</ViewCell>
</DataTemplate>
</Listview.ItemTemplate>
</ListView>
My c# code :
......
DentistList.ItemSource = new List<Doctor>
{
// List of items defined here like...
Name = "ABC",
ImagePath = "img1.jpg"
// Etc...
};
Now, Below this list, I want to change style(like, fontsize etc...) of label and image. But I can not access them.
I tried to access them with FindByName() method but could not do that.
So, can anyone please answer ?
Thank you in advance.
From Jason's comment, you can change the Label.FontSize and Label.TextColor using OnIdiom like so:
<Label Text="{Binding Name}" x:Name="DoctorName">
<Label.TextColor>
<OnIdiom x:TypeArguments="Color"
Phone="Yellow"
Tablet="Blue"/>
</Label.TextColor>
<Label.FontSize>
<OnIdiom x:TypeArguments="NamedSize"
Phone="Small"
Tablet="Large"/>
</Label.FontSize>
</Label>
*Edit: Example using regular integer:
<Label.FontSize>
<OnIdiom x:TypeArguments="x:Double"
Phone="20"
Tablet="30"/>
</Label.FontSize>
*Edit #2:
If you plan to use your Label.FontSize and Label.TextColor on multiple pages I would suggest adding the values into your App.xaml and then referencing them from your ContentPages (you could also just add the value to the ContentPage's ResourceDictionary if you are using the values multiple times but only on a single page):
App.xaml:
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.App">
<Application.Resources>
<ResourceDictionary>
<Color x:Key="MyTextColor">
<Color.Accent>
<OnIdiom x:TypeArguments="Color"
Phone="Yellow"
Tablet="Blue"/>
</Color.Accent>
</Color>
<x:Double x:Key="MyFontSize">
<OnIdiom x:TypeArguments="x:Double"
Phone="20"
Tablet="30"/>
</x:Double>
</ResourceDictionary>
</Application.Resources>
</Application>
Now in your ContentPages:
<Label x:Name="DoctorName"
Text="{Binding Name}"
TextColor="{StaticResource MyTextColor}"
FontSize="{StaticResource MyFontSize}"/>
If you want to use NamedSize instead you might need to use converter that I have seen on the Xamarin Forums. Let me know if you cannot find it and I can try to look around.
Related
Is it possible to scale labels, buttons, and frames with font size? I'm running into accessibility issues, where iOS has a few lines to disable all accessibility scaling and after googling android doesn't seem to have it at all. I have a number of components that have text inside and buttons that have custom fonts for arrows pause and play icons which are custom fonts. I need to scale the entire button around depending if the font size within the accessibility has been changed.
Only for iOS: Accessibility Scaling for Named Font Sizes on iOS, cannot find anything about android.
Another post: Getting Android/iOS Accessibility font sizes, first answer has this line of code for android Android.Content.Res.Resources.System.Configuration.FontScale but I can't seem to be able to access the Android.Content anywhere I try to use it.
Many Thanks in advance.
Edit: Temp Fix. Still would like to know if its even possible to do component scaling with fontsize.
Reference:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BugTestMediaElement.Page3">
<Shell.TitleView>
<StackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Red">
<Frame BackgroundColor="White"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand">
<Label Text="Test"
FontSize="{StaticResource ToolbarIconFontSize}"
TextColor="Black" />
</Frame>
</StackLayout>
</Shell.TitleView>
</ContentPage>
I use the following approach. In App.xaml file (application wide declarations), I make the following declarations:
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:Key="ToolbarIconFontSize" x:TypeArguments="x:Double" Android="48" iOS="64" />
</ResourceDictionary>
</Application.Resources>
Then on a page (I use icons from FontAwesome), I make this declaration:
<Shell.TitleView>
<Grid Style="{StaticResource GridTitle}" RowDefinitions="*" ColumnDefinitions="*, 0.20*, 0.20*">
<!-- other declarations are skipped -->
<ImageButton Grid.Row="0" Grid.Column="1" HorizontalOptions="Start" Command="{Binding SomeActionCommand}">
<ImageButton.Source>
<FontImageSource Glyph="{x:Static icons:IconFontGlyphNames.SomeActionSymbol}"
FontFamily="IconFontFamily"
Color="White"
Size="{StaticResource ToolbarIconFontSize}" />
</ImageButton.Source>
</ImageButton>
<!-- other declarations are skipped -->
</Grid>
</Shell.TitleView>
IconFontGlyphNames class declarations look like that:
public static class IconFontGlyphNames
{
public const string SomeActionSymbol = "\uf234";
// other declarations are skipped
}
I set fonts sizes for icons, and texts using this approach, and it works fine as for Android and for iOS platform.
Update #1. Explaining `Shell.TitleView` location.
Shell.TitleView is located here:
<ContentPage>
<Shell.TitleView>
<!-- Shell title view elements go here -->
</Shell.TitleView>
<ContentPage.Content>
<!-- Your page body elements go here -->
</ContentPage.Content>
</ContentPage>
I'm developing a WPF app using MVVM pattern with Caliburn.Micro
I have a config file that contains positions of where XAML elements should be inside of a StackPanel
# in this case RU_ELEMENT should be at the top, EN_ELEMENT second and DE_ELEMENT last
EN_ELEMENT = 1
DE_ELEMENT = 2
RU_ELEMENT = 0
This seems to be pretty basic yet I'm unable to find a way to do this. I found this thread: change the children index of stackpanel in wpf but changing it this way seems to be too complicated for what I am after. I just need to set an index of an element from a variable. I feel like there should be a much simpler way. I'm also ok with using some other, perhaps more appropriate layout panel than StackPanel.
XAML:
<!-- Language1 -->
<TextBlock Text="English" Foreground="DarkGray" FontSize="16"/>
<TextBox
VerticalAlignment="Top"
Height="150"
Text="{Binding SelectedItem.ValueEN, UpdateSourceTrigger=PropertyChanged}"
cm:Message.Attach="[Event GotFocus] = [Action FocusedTextBox('english')]" />
<!-- Language2 -->
<TextBlock Text="German" Foreground="DarkGray" FontSize="16"/>
<TextBox
VerticalAlignment="Top"
Height="150"
Text="{Binding SelectedItem.ValueDE, UpdateSourceTrigger=PropertyChanged}"
cm:Message.Attach="[Event GotFocus] = [Action FocusedTextBox('german')]" />
On a side note: I find WPF and C# in general to have much less discussions and "how to" guides than all of my previous languages (Java, Python, JS) so researching things online is usually a dead end for me. I'm not sure to why that is since C# is a very popular language but I'm really struggling with finding help online.
A solution could be to use an ItemsControl that would host the xaml elements. You can bind the items like <ItemsControl ItemsSource="{Binding ListOfItems} ...
Then you could easily sort the items in the corresponding ViewModel. Like so:
public BindableCollection<YourElement> ListOfItems {get;set;}
...
ListOfItems.Sort()
Note that YourElement class should have a comparator.
EDIT: As per request I'll explain it more detailed:
In your Xaml you have to declare a ItemsControl like so:
<ItemsControl ItemsSource="{Binding ListOfItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Language}" Foreground="DarkGray" FontSize="16"/>
<TextBox
VerticalAlignment="Top"
Height="150"
Text="{Binding TextValue, UpdateSourceTrigger=PropertyChanged}"
cm:Message.Attach="[Event GotFocus] = [Action FocusedTextBox($this)]" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
And in your backend you should first create a class that's going to represent your item in the ItemsControl. For example:
public Class MyItem{
public string Language {get;set;}
public string TextValue {get;set;}
}
Finally in your ViewModel you'll need to create the list of items that you bind with the ItemsControl like so:
public BindableCollection<MyItem> ListOfItems {get;set;}= new BindableCollection<MyItem>();
//here you can add them in the order that is specified by the config file
public void LoadItems(){
ListOfItems.Add(new MyItem{Language="English"});
ListOfItems.Add(new MyItem{Language="Russian"});
ListOfItems.Add(new MyItem{Language="German"});
}
public void FocusedTextBox(MyItem item){
//do here whatever you want
}
Ok, this is a little strange, but I need to take a screenshot of a list of items in Xamarin. The problem is that I'm using a ListView and it only renders about 5 items. I need to render all elements in the list. I don't care if it's smaller on-screen; I just want to take a screenshot of the view and be able to share it.
This is my .xaml:
<BoxView HorizontalOptions="FillAndExpand" HeightRequest="0.5" Color="Gray"/>
<controls:CustomListView x:Name="list"
ItemsSource="{Binding List}"
HeightRequest="1000" VerticalOptions="Fill"
HasUnevenRows="True">
<x:Arguments>
<ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
</x:Arguments>
<controls:CustomListView.ItemTemplate>
<DataTemplate>
<cell:ItemViewCell></cell:ItemViewCell>
</DataTemplate>
</controls:CustomListView.ItemTemplate>
</controls:CustomListView>
<BoxView HorizontalOptions="FillAndExpand" HeightRequest="0.5" Color="Gray"/>
This is for Android.
In the code behind you something like this on the OnAppearing method
list.HeightRequested = list.ItemSource.Count * list.RowHeight;
you can also try to do the same thing on the CustomList's OnPropertyChanged where propertyName is ItemSource whatever feels best for you
I had to create pdf, it is not possible to "overlap" the boundaries of the screen, At least no with a List, I went the pdf way
I have created a global font resource in App.xaml like this:
<Application.Resources>
<ResourceDictionary>
<FontFamily x:Key="GlobalFontLight">Arial</FontFamily>
<FontFamily x:Key="GlobalFont">Segoe UI</FontFamily>
<FontFamily x:Key="GlobalFontBold">Caibri</FontFamily>
</ResourceDictionary>
</Application.Resources>
In MainPage I have added a TextBlock:
<TextBlock Text="Some text" FontFamily="{StaticResource GlobalFont}" Foreground="Black"/>
<TextBlock Text="Some text 2" FontFamily="{StaticResource GlobalFontLight}" Foreground="Black"/>
<TextBlock Text="Some text 3" FontFamily="{StaticResource GlobalFontBold}" Foreground="Black"/>
And it is ok, TextBlock use my global font.
Now, I want to change that global font in Application Resources. I have tried next code:
Application.Current.Resources["GlobalFont"] = new FontFamily("Arial");
But nothing happens, TextBlock still use the old font. If I run this code before InitializeComponent(); then it is working as I want, but after that no. Anyone knows what do I do wrong? How to achieve this dynamic change of font?
Because UWP does not support DynamicResource this is quite a problem. The StaticResource and ThemeResource extensions won't save you here, because they are bound only when evaluated and will not update for the already-evaluated properties when the underlying resource changes.
The first option would be to navigate back and navigate to the same page again, so that the controls get reloaded and the resources evaluated anew.
If you want something more dynamic, please check out my answer on this SO question. If you follow that solution, you can create a class implementing INotifyPropertyChanged that will contain a property of type FontFamily, store this instance in a StaticResource and then use binding instead of StaticResource like this:
<TextBlock Text="{Binding Font, Source={StaticResource CustomUISettings}}" />
I have problems with matching Ressource Dictionaries for a specific type in my project.
At start of my application my programm takes all .dll files in the folder and bind the .dlls to my project. After that I will search in all Assemblies for .xaml Files also the Ressource Dictionaries in my different dlls.
At the end I got a list with my Ressource Dictionaries.
Okay here is my problem now...How can I select the right dictionary for my type in the list View dynamicly. The second thing is how can I match the Dictionary Templates only to 1 control in my Window?
When the type of the items in my list view are changing check again for the right dictionary maybe i need another one
Here is an example of 1 dictionary
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PresentObjectDataTemplate">
<Style TargetType="ListView">
<!-- My Style for my ListView Control-->
</Style>
<!-- My Data Templates only for 1 Control-->
<DataTemplate DataType="{x:Type local:Entity1}">
<StackPanel>
<TextBox Text="{Binding A1}"/>
<TextBox Text="{Binding A2}"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Entity2}">
<StackPanel>
<TextBox Text="{Binding A1}"/>
<TextBox Text="{Binding A2}"/>
</StackPanel>
</DataTemplate>
My MainWindow has 3 Controls
A treeView to select my List
A listview to show the objects in the list
A contentcontrol to show the properties of a selected object
When I merge the dictionary to the window ressources my list view and my content control will use the datatemplates. But i want that the templates only used in the contentcontrol
Here a picture from my idea for better understanding
myPicture