It is possible to add multiple Bindings to a Label using XAML, for example:
<Label Text = "{Binding Address} - {Binding City} / {Binding State}" TextColor = "# ffeece" />
No, this is not possible.
But why not concatenate it in your ViewModel and bind to that?
public string Description
{
get { return $"{Address} - {City} / {State}"; }
}
And bind it like: <Label Text = "{Binding Description}" TextColor = "# ffeece" />
I'm not sure if you can add multiple binding to the same property. but you can use like the above answer or use a value converter by passing the object through and returning the formatted string.
If you want to bind different properties on one control in XAML in this situation you have to bind the properties in your view model, then easily you can bind. You can refer above example.
Related
I want to display a binding field in a label. It's easy in XAML but how to do it in code-behind? In XAML,
<Label Text="{Binding LastName}" Style="{StaticResource MyLabel}"/>.
In my code behind, I have tried:
Label ln = new Label();
ln.BindingContext = "ContactsModel";
ln.SetBinding = "LastName";
which does not work and I have no clue how to set the Style.
If you read the Basic Binding documentation, then it clearly states that to bind a view you have to.
Specify a BindingContext
Use the SetBinding method to specify the target property to be bound to which ViewModel source property.
The BindingContext may be inferred from the parent element and does not always have to be specified, but your binding should look more like:
var label = new Label();
label.SetBinding(Label.TextProperty, "LastName");
This will bind the Text property on the label to LastName in the ViewModel.
I am trying to create custom control in Xamarin.Forms which has the unique id for automation. So, i have set the android renderer's contentDescription property. So, i can get the AppResult.Label property to identify the control. But, my requirements is that how to get the control's text property? What property i have to set in control level with the corresponding text to get it in AppResult.Text property.
[Test]
[Description("SampleTest")]
public void WelcomeTextIsDisplayed()
{
App.Repl();
AppResult[] results = App.WaitForElement("myControl");
Assert.IsTrue(results[0].Text == "My Control Text", results[0].Text + "\n" + results[0].Description + "\n" + results[0].Id + "\n" + results[0].Label);
}
For more information, I have prepared the simple example to explain better about my case. Here, i have derived my custom control from Grid and i introduced the Text property. When i try to view the element using Repl() method, it does not show the Text property but it shows the text properties for Label & Entry controls.
<StackLayout >
<Label Text="Hello, Custom Renderer!" />
<local:MyEntry Text="In Shared Code" AutomationId="myEntry" />
<local1:CustomView Text="Sample" BackgroundColor="Red" HeightRequest="500" AutomationId="customControl" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"/>
</StackLayout>
public class CustomView : Grid
{
public CustomView()
{
}
public static readonly BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(string),string.Empty);
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
Result while calling App.Repl() ,
I'm not sure how different Xamarin.Forms are to Xamarin.Android (which is mostly what my experience is in.)
What happens if you try
app.Query(c => c.Id("NoResourceEntry-2").Property("Text")).SingleOrDefault();
or some variation of the above? Can you then do something with this? I Hope this helps or points you in the right direction.
Try to use with index position like this:
app.Query(c=>c.Id("NoResourceEntry-2"))[0].Text
similarly you can use class for same:
app.Query(c=>c.Class("LabelRenderer"))[0].Text
Query for Class("LabelRenderer") gave 2 results. So in above example, you can see it gave you 2 results but you have to use index for particular result.
Please let me know if Ill be able to bind a property value of a view model to a XAML control.
XAML:
<Emtry x:Key="addressLine1" />
ViewModel:
public string addressLine1 { get; set; }
Is it possible to create a two way binding?
You will have to do it like this: <Entry Text="{Binding addressLine1, Mode=TwoWay}" />
The x:Key doesn't have much to do with it. You will have to bind to the property of the control that you want to use. In this case, on the Entry you want to bind it to the Text property so you can show it to the user and the user can edit it.
Then with the notation of {Binding addressLine1, Mode=TwoWay} you specify which property of the view model to bind to and what the mode should be. You can leave the mode out, then it will have the default value which is OneWay most of the time.
To make the connection between the XAML and the view model, you will still have to specify the DataBinding property on the code-behind of the XAML page.
<Entry x:Name="entAddress" Text="{Binding addressLine1}"/>
How can I hide contentview using binding.How to use binding in On platform argument? please check following screen shot for issue.
In screeen shot example like showjoin isvisible true. then it's fine. but showjoin is false then by default contentview is displayed because of in onflatform is true.
please help me too sort-out this issue
If all you are wanting to do is hide the ContentView when your platform is Android, I would suggest using the OnPlatform in your xaml. Also, setting the IsVisible property of a ContentView twice won't work well usually.
Using your xaml from above:
<OnPlatform x:TypeArguments="View">
<On Platform="iOS">
<ContentView Margin="20,10,20,20" HeightRequest="40">
<!-- Rest of ContentView code -->
</ContentView>
</On>
<!-- You must specify an Android view -->
<On Platform="Android">
<!-- Use a simple boxview with height and width 0 to create an empty view -->
<BoxView HeightRequest="0" WidthRequest="0" IsVisible="False"/>
</On>
</OnPlatform>
This will only show the ContentView on your page when using iOS and nothing on Android.
a) Create one Boolean property in Viewmodel e.g. IsContentViewVisible
b) Bind this property to contentview IsVisible property e.g. IsVisible = "{Binding IsContentViewVisible}", also make sure Raisepropertychanged event should be in place.
c) As per your need you set the IsContentViewVisible property to False/true in your ViewModel
The question is not all to clear... but if you want to avoid the XAML OnPlatform override ( because it is not using Binding ), you can delete it in XAML and just add the correct logic in your ShowJoinButton bool property.
You can check platform in code ( even in your ViewModel ) like so:
if(Device.RuntimePlatform == Device.iOS) ...
If you still want to have everything in XAML, that is also possible of course.
You can use Binding inside OnPlatform, thing to take note is the type argument has to be BindingBase!
<OnPlatform x:TypeArguments="BindingBase" iOS="{Binding MyBool}" Android="{Binding MyBool}"/>
Below is the code to write binding in ViewModel class
private const string ShowJoinButtonPropertyName = "ShowJoinButton";
private bool showJoinButton = false;
public bool ShowJoinButton
{
get { return showJoinButton; }
set { SetProperty(ref showJoinButton, value, ShowJoinButtonPropertyName); }
}
Wherever you want to hide/show you need to use the below code
if (Device.RuntimePlatform == Device.Android)
{
ShowJoinButton = false;
}
else
{
ShowJoinButton = true;
}
Hope it helps!
I'm doing WP7 app using Panorama control and have a problem with binding into Panorama Title property. Is it possible to bind that value out from ViewModel object?
Binding in xaml file:
<controls:Panorama x:Name="prmPanorama" Title="{Binding Voyage.Title}">
Voyage property of ViewModel is a Model entity (with Title property inside) with OnNotifyPropertyChanged event fired every time it changes:
private Voyage _voyage;
public Voyage Voyage
{
get { return _voyage; }
set
{
if (_voyage != value)
{
_voyage = value;
OnNotifyPropertyChanged("Voyage");
}
}
}
When I bind the same property into another control, eg. TextBlock, binding works just fine:
<TextBlock Text="{Binding Voyage.Title}" />
The text shown in that text block is as it should be but on the same time panorama title is not binded right - it's collapsed.
Does anyone tried to do that kind of binding? I have no idea why it doesn't work.
<DataTemplate x:Key="TitleDataTemplate">
<TextBlock Text="{Binding}" />
</DataTemplate>
...
<controls:Panorama Title="{Binding Voyage.Title}"
TitleTemplate="{StaticResource TitleDataTemplate}">
The control template of the panorama control uses a content presenter to display whatever value the its title property has kind of like a button. When setting the title template property, you indirectly set the content template of the content presenter.
That is why you have to set the title property on the panorama control and then can use that value in your title template for binding. In other words its not enough to just bind to the title you have to give it a template.
Check out this link for more info