I am creating a ListView whose items I want to directly control with code. I have the following xaml that declares a generic ListView.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ViewCellClick"
x:Class="ViewCellClick.MainPage">
<ListView x:Name="___listview" HasUnevenRows="True">
<ListView.ItemTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
and then in the code behind, I set up the ItemsSource property.
namespace ViewCellClick
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
___listview.ItemsSource = Repository.GetList();
___listview.ItemTemplate = new DataTemplate(typeof(CustomViewCell));
}
}
and this leverages a custom template defined as...
public class CustomViewCell : ViewCell
{
public CustomViewCell()
{
var stack = new StackLayout();
stack.Children.Add(new Label() { Text = "Label" });
// HOW DO I ACCESS THE MODEL HERE SO I CAN DRAW CUSTOM UI DEPENDING ON THE MODEL INSTANCE?
View = stack;
}
}
}
at this level, I have a very generic custom view cell as it only creates a label. However, say the model is complicated, and depending on the data in the model I would draw a different UI for that ViewCell instance.
How do I get access to the model for each CustomViewCell and then draw the UI according to that model?
I tried BindingContext, but it's null in the CustomViewCell constructor.
The BindingContext of thew ViewCell will have a reference to the current item in the list. You will need to cast it to the appropriate type in order to use it.
Related
I have this template that's simplified for the question:
<?xml version="1.0" encoding="UTF-8"?>
<Frame xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:t="clr-namespace:Japanese.Templates"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.Templates.RoundButtonText" x:Name="this">
<Label Text="ABC" />
</Frame>
and this C#
using Xamarin.Forms;
namespace Japanese.Templates
{
public partial class RoundButtonText : BaseFrameButtonTemplate
{
public RoundButtonText()
{
InitializeComponent();
?? = Color.Red;
}
}
}
Can someone help me by telling me how I can change the TextColor of the label in the XAML inside the constructor of the back-end C#. Note that there's much more to this but I'm simplifying what I need for the question as if I know this then I can do the rest.
Specify x:Name="MyLabel" on the Label you want to access.
Then you can access that Label in your back-end C# file like so:
public RoundButtonText()
{
InitializeComponent();
MyLabel.TextColor = Color.Red; //OR
MyLabel.BackgroundColor = Color.Red;
}
That allows you to be able access any public property on the Label
I have this XAML:
<TableSection x:Name="TS2">
<TableSection.Title>
ABC
</TableSection.Title>
<ViewCell x:Name="noa" Tapped="openPicker">
...
</ViewCell>
<ViewCell x:Name="prt" Tapped="openPicker">
...
</ViewCell>
</TableSection>
C#
public partial class TableViewFooter : ViewCell
{
public TableViewFooter()
{
InitializeComponent();
}
}
How can I add a ViewCell (created from new TableViewFooter("AAA",60)) after second ViewCell in C#.
var cmt = new TableViewFooter("AAA",60);
prt.Add(cmt);
This code as is gives an error saying:
Error CS7036: There is no argument given that corresponds to the
required formal parameter 'value' of
'SettersExtensions.Add(IList, BindableProperty, object)'
(CS7036)
You can't add a ViewCell to a ViewCell - but you can append it to TableSection - for e.g., try using:
TS2.Add(cmt);
I wan't to create a ContentView with a BindableProperty of type DataTemplate, so that when I use my custom ContentView i can customize how the elements should look like.
But I wan't to arrange and create the contents in code, how can I create an instance from a DataTemplate?
For example, in my custom view, I have a collection of objects, now for each object I want to create a view based on the set data template and set the binding context of that created view to that object.
I worked it out in following way.
I use my custom ContentView in following way:
<controls:MyCustomView Items="{Binding SampleItems}">
<controls:MyCustomView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding SampleProperty}" />
</DataTemplate>
</controls:MyCustomView.ItemTemplate>
</controls:MyCustomView>
then in the code behind of the MyCustomView I declare a ItemTemplate bindable property:
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create(
nameof(ItemTemplate),
typeof(DataTemplate),
typeof(MyCustomView),
propertyChanged: (bObj, oldValue, newValue) =>
{
var view = bObj as MyCustomView;
if (view != null)
view.SampleMethodToArrangeItems();
}
);
now let's say that in the SampleMethodToArrangeItems method I want to create and arrange, the items created from the provided data template:
foreach (var item in Items)
{
var itemView = ItemTemplate.CreateContent() as View;
if (itemView != null)
{
itemView.BindingContext = item;
// Do something with the create view e.g. add it to Grid.Children
}
}
I have Xamarin Forms xaml:
// MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:BlankAppXamlXamarinForms"
x:Class="BlankAppXamlXamarinForms.MainPage">
<Label Text="{Binding myProperty}" />
</ContentPage>
And I have code behind:
// MainPage.xaml.cs
namespace BlankAppXamlXamarinForms {
public partial class MainPage : ContentPage
{
public string myProperty= "MY TEXT";
public MainPage()
{
InitializeComponent();
BindingContext = this;
}
}
}
It should bind myProperty to label's text. However, nothing displays in the label. How to bind myProperty to label's text? (I know I should use ViewModel to be able to notify view about changes of the property but in this example I really just want to bind myProperty from code behind to the label)
You need to declare that you can "get" the variable.
public string myProperty { get; } = "MY TEXT";
If you actually want to change this variable in code, your class will need to implement INotifyPropertyChanged, otherwise it will always be "MY TEXT"
I have this XAML:
<ListBox x:Name="MyItemsList"
ItemsSource="{Binding MyItems}"
SelectionChanged="ItemsList_SelectionChanged">
The code behind assigns the datacontext of the page to the view model:
DataContext = App.ViewModel;
My ViewModel object defines MyItems (and I initialize MyItems before setting the DataContext):
public ObservableCollection<Item> MyItems;
The end result is that my ListBox doesn't display anything. I tried adding items after the binding, and they don't show up either.
What works is if I set the ItemsSource in code instead of in the XAML:
MyItemsList.ItemsSource = App.ViewModel.MyItems;
Any tips on why this would happen? Thanks.
public ObservableCollection MyItems; - Field, but you should use property!
Property with backing field:
private ObservableCollection<Item> _myItems = new ObservableCollection<Item>();
public ObservableCollection<Item> MyItems{get{return _myItems;}}
If you whant setter, you should implement INotifyPropertyChanged and call OnPropertyChanged("MyItems")