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.
Related
Here is the XAML Code from the documentation:
<StackLayout>
<CarouselView ItemsSource="{Binding Monkeys}"
IndicatorView="indicatorView">
<CarouselView.ItemTemplate>
<!-- DataTemplate that defines item appearance -->
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView x:Name="indicatorView"/>
</StackLayout>
I am using C# Markup so my code looks like this (styling code and some layout settings removed to keep simple for SO question):
CarouselView ScrollingImageView() => new CarouselView
{
ItemTemplate = new DataTemplate(() =>
{})
}
.Bind(ItemsView.ItemsSourceProperty, nameof(_vm.ListOfItems))
.Bind(CarouselView.PositionProperty, nameof(_vm.ScrollingImageViewerPosition));
IndicatorView IndicatorView() => new IndicatorView
{
IndicatorsShape = IndicatorShape.Circle,
};
Grid ButtonIndicatorGrid() => new Grid
{
Children = { IndicatorView().Row(0).Column(1) }
};
void Build() => Content =
new Grid
{
Children = {
ScrollingImageView().Row(0),
ButtonIndicatorGrid().Row(1),
}
};
In this example, the IndicatorView is rendered beneath the
CarouselView, with an indicator for each item in the CarouselView. The
IndicatorView is populated with data by setting the
CarouselView.IndicatorView property to the IndicatorView object. Each
indicator is a light gray circle, while the indicator that represents
the current item in the CarouselView is dark gray. Setting the
CarouselView.IndicatorView property results in the
IndicatorView.Position property binding to the CarouselView.Position
property, and the IndicatorView.ItemsSource property binding to the
CarouselView.ItemsSource property.
Now I cannot find an example of how to do this with C#. In XAML it works by setting the name but how can I do the same thing in C# as from what I understand (please correct me if wrong), I cannot set the name in C# in the same way as in XAML.
you need to maintain a reference to your UI objects when you create them
var iv = IndicatorView();
var cv = ScrollingImageView();
cv.IndicatorView = iv;
In my Xamarin.Forms Shell application, I define the flyout items in the AppShell.xaml.cs file and not in the AppShell.xaml one since I need to define them programmatically. Here, I read I can use the FlyoutDisplayOptions.AsMultipleItems value to get separators. So, I don’t understand why Xamarin doesn’t show separators when I use the ShellSection elements and set their FlyoutDisplayOptions as FlyoutDisplayOptions.AsMultipleItems. The code through which I define the flyout items is the following:
var nli = new FlyoutItem { FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems };
var nc = new ShellSection { FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems };
foreach (var kind in kinds) { // "kinds" is retrieved from a service
var csc = new ShellContent { /* ... */ };
nc.Items.Add(csc);
}
nli.Items.Add(nc);
ShellItems.Items.Add(nli);
The red area is the one populated by the foreach statement. The FlyoutItem and ShellSection parents have the FlyoutDisplayOptions correctly set, but the separators are not shown between the ShellContent elements. Why?
To add a separator between FlyoutItems or MenuItems, you can add a MenuItem with a DataTemplate as below:
<MenuItem>
<Shell.MenuItemTemplate>
<DataTemplate>
<Label HeightRequest="1" BackgroundColor="LightGray"></Label>
</DataTemplate>
</Shell.MenuItemTemplate>
</MenuItem>
You can perhaps convert this into code-behind.
Here is how it looks:
It should be a default phenomenon in shell, there is no separators between the items in FlyoutItem.
You could have a look at the official document:
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}"/>
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.
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