CarouselView.Content is empty - c#

I try study is new componet CarouselView and с# in total.
But I have problem.
This code display is empty content in CarouselView. Why?
I send is fill code my colutions.
<?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:carousel="clr-namespace:CarouselView.FormsPlugin.Abstractions;assembly=CarouselView.FormsPlugin.Abstractions"
xmlns:local="clr-namespace:App6"
x:Class="App6.MainPage">
<StackLayout>
<Image Source="home.png"/>
<carousel:CarouselViewControl x:Name="MyCV" BackgroundColor="Black">
<carousel:CarouselViewControl.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding TestLine}"></Label>
</StackLayout>
</DataTemplate>
</carousel:CarouselViewControl.ItemTemplate>
</carousel:CarouselViewControl>
</StackLayout>
</ContentPage>
namespace App6
{
public partial class MainPage : ContentPage
{
class CustomCell
{
public string TestLine { get; set; }
}
public MainPage()
{
InitializeComponent();
List<CustomCell> myCarousel = new List<CustomCell>();
myCarousel.Add(new CustomCell { TestLine = "Line 1" });
myCarousel.Add(new CustomCell { TestLine = "Line 2" });
MyCV.ItemsSource = myCarousel;
}
}
}

Your code is correct, so your problem is in the visual layer. Try to define the height and width wherever possible and it should resolve the problem. CarouselView isn't the official control and isn't up to standards of Xamarin's built-in controls so it has some somewhat unexpected behaviors like this.

Related

.NET MAUI Binding Issue

Newbie to .NET MAUI and to MVVM. I've seen other examples out there for this, but mine won't work. When I run the code it shows the string PlayProperty in PlayMCanvas as null. I don't know how to get data into the canvas.
VM
public class ShowViewModel
{
public string TheString {get;set; }
public ShowViewModel()
{
TheString = "test";
}
}
View Code Behind
public partial class ShowPlay : ContentPage
{
public ShowViewModel TheVM;
public ShowPlay()
{
InitializeComponent();
TheVM = new ShowViewModel();
TheVM.TheString = "test2";
BindingContext = TheVM;
}
}
XAML View
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:drawables="clr-namespace:PlayMApp.Drawables"
xmlns:local="clr-namespace:PlayMApp"
x:Class="PlayMApp.ShowPlay"
x:DataType="local:ShowViewModel"
Title="Show Play">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI!"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Button
Text="Add Motion"
Clicked="AddMotion"
VerticalOptions="Start"
HorizontalOptions="Center"></Button>
<GraphicsView HeightRequest="300"
WidthRequest="400">
<GraphicsView.Drawable>
<drawables:PlayMCanvas Play="{ Binding TheString }" />
</GraphicsView.Drawable>
</GraphicsView>
</VerticalStackLayout>
</ContentPage>
PlayMCanvas
public class PlayMCanvas : GraphicsView, IDrawable
{
public PlayMCanvas()
{
}
public string Play
{
get => (string)GetValue(PlayProperty);
set => SetValue(PlayProperty, value);
}
public static BindableProperty PlayProperty = BindableProperty.Create(nameof(Play), typeof(string), typeof(PlayMCanvas));
public void Draw(ICanvas canvas, RectF dirtyRect)
{
canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 6;
canvas.DrawLine(10, 10, 90, 100);
canvas.DrawString(Play,40,30,HorizontalAlignment.Left);
}
}
When I get to the final line (DrawString), I think Play should be "test2", but it's null
I've tried making changes to the code to tweak what is sent in. If I send just a plain literal string through the <drawables:PlayMCanvas Play="test" />, it works, but not with the binding
I figured it out, saw another example where someone was very specific in the component they were binding to and followed that.
Added x:Name to the PlayMCanvas like below:
<drawables:PlayMCanvas x:Name="PlayMCan" Play="{Binding TheString}" />
Changed to this in codebehind:
PlayMCan.BindingContext = TheVM;
And now the binding seems to be working.
Thanks for the comments!

.net Maui binding values multiple levels deep

How can I Pass a Binding from a Page to a View?
I have this Page(Xaml)
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:DataBindingTests.Views"
xmlns:model="clr-namespace:DataBindingTests.ViewModels"
x:Class="DataBindingTests.Pages.CoolePage"
Title="CoolePage"
x:DataType="model:CoolesModel">
<VerticalStackLayout>
<Label Text="{Binding YourName}"></Label>
<views:MainView YourName="{Binding YourName}"></views:MainView>
<Button Command="{Binding ChangeNameCommand}"></Button>
</VerticalStackLayout>
</ContentPage>
And its CodeBehind:
using DataBindingTests.ViewModels;
namespace DataBindingTests.Pages;
public partial class CoolePage : ContentPage
{
public CoolePage()
{
this.BindingContext = new CoolesModel();
InitializeComponent();
}
}
If I pass a String into my MainView it works and all events are fired. When I use the binding it doesn't. In this simple test, the app should display two times the same name, but only the Label of the ContentPage has the YourName property printed
<views:MainView YourName="Lars"></views:MainView> <-- Works
<views:MainView YourName="{Binding YourName}"></views:MainView> <-- doesn't work
This is the Xaml of the MainView
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:DataBindingTests.Views"
x:Class="DataBindingTests.Views.MainView">
<VerticalStackLayout>
<Label Text="{Binding YourName}"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
This is the CodeBehind of the MainView
namespace DataBindingTests.Views;
public partial class MainView : ContentView
{
public String YourName
{
get
{
String value = (String)GetValue(MainView.YourNameProperty);
return value;
}
set
{
SetValue(MainView.YourNameProperty, value);
}
}
public static readonly BindableProperty YourNameProperty = BindableProperty.Create(nameof(YourName)
, typeof(String)
, typeof(MainView), defaultBindingMode:BindingMode.TwoWay, propertyChanged: OnYourNameChanged);
static void OnYourNameChanged(BindableObject bindable, object oldValue, object newValue)
{
Console.WriteLine(newValue);
}
public MainView()
{
this.BindingContext = this; // Ignore ParentContext
InitializeComponent();
}
}
You can just remove code this.BindingContext = this; from the constructor of MainView.xaml.cs:
public MainView()
{
//this.BindingContext = this;
InitializeComponent();
}
Update:
the above code would only work because the Property in the View and
the Page have the same name.
In this condition, you can modify the code of MainView.xaml as follows:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp929.MainView"
x:Name="TestControlView"
>
<VerticalStackLayout>
<Label Text="{Binding Source={x:Reference TestControlView}, Path=YourName}"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
MainView.xaml.cs
public partial class MainView : ContentView
{
public String YourName
{
get
{
String value = (String)GetValue(YourNameProperty);
return value;
}
set
{
SetValue(YourNameProperty, value);
}
}
public static readonly BindableProperty YourNameProperty = BindableProperty.Create(nameof(YourName)
, typeof(String)
, typeof(MainView), defaultBindingMode: BindingMode.TwoWay, propertyChanged: OnYourNameChanged);
static void OnYourNameChanged(BindableObject bindable, object oldValue, object newValue)
{
Console.WriteLine("-----------------> "+newValue);
}
public MainView()
      {
            InitializeComponent();
// this.BindingContext = this;
}
}
CoolesModel.cs
public class CoolesModel
{
// public string YourName { get; set; }
public string Name { get; set; }
public string TestName { get; set; }
public ICommand ChangeNameCommand => new Command(changeMethod);
private void changeMethod()
{
}
public CoolesModel() {
//YourName = "abc";
Name = "abc";
TestName = "test123...";
}
}
MainPage.xaml.cs
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:mauiapp929="clr-namespace:MauiApp929"
x:Class="MauiApp929.MainPage">
<ScrollView>
<VerticalStackLayout>
<Label Text="{Binding Name}"></Label>
<mauiapp929:MainView YourName="{Binding TestName}"></mauiapp929:MainView>
<Button Command="{Binding ChangeNameCommand}"></Button>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
In this simple test, the app should display two times the same name, but only the Label of the ContentPage has the YourName property printed
You're overwriting your binding context half way through for some reason, and the context your page binding resolves (the normal way of using it, the parent context) is different than what you actually see on the screen (which is your this.BindingContext = this). And you never set your second context's property.

Xamarin Cross Platform Picker not binding correctly

I am new to Xamarin Cross Platform apps
I am trying to bind a Picker ItemSource to a List and display one property, with out success! My reference has been from here
Please can some one advise where my error is, my View or Xmal please (or probably both)
The List is a List of StdGrades defined as
namespace FitRestults_Dev1
{
class StdGrade
{
public string Gradelbl
{ get; set; }
public string Grade
{ get; set; }
public static List<StdGrade> Grades()
{
List<StdGrade> GradesList = new List<StdGrade>(){
new StdGrade(){ Gradelbl="10th Gup (White belt)", Grade="G10"},
new StdGrade(){ Gradelbl="9th Gup (Organge belt)", Grade="G9"},
new StdGrade(){ Gradelbl="8th Gup (Organge belt 1 tag)", Grade="G8"},
... };
return GradesList;
}
public List<StdGrade> GradesList => Grades();
public static string GetGrade(string Input)
{
List<StdGrade> GradesList = Grades();
var result = (from r in GradesList where r.Gradelbl == Input select r).First();
return result.Grade;
}
}
For the Content page I have defined a simple view as
namespace FitRestults_Dev1
{
class AddStudentView
{
List<StdGrade> _GradeList;
public List<StdGrade> GradeList
{ get => _GradeList;
set
{
_GradeList = StdGrade.Grades();
}
}
}
}
My content page xmal is
<?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="FitRestults_Dev1.AddStudent"
xmlns:src="clr-namespace:FitRestults_Dev1"
>
<ContentPage.BindingContext>
<src:AddStudentView/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout Padding="10" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Grid>
…
<Picker x:Name="GradePicker" Title="Select a Grade" Grid.Row="2" Grid.Column="1" MinimumWidthRequest="100" FontSize="12"
ItemsSource="GradeList" SelectedIndex="0" ItemDisplayBinding="{Binding Gradelbl}">
</Picker>
</StackLayout>
</ContentPage.Content>
</ContentPage>
You are providing the itemsSource the incorrect way it should be a binding
ItemsSource={Binding GradeList}
Also Stop using Generic.List for binding, MVVM with Xamarin Forms should have ObservableCollections as it inherits from INotifyPropertyChanged and INotifyCollectionChanged

Xamarin.Forms: bind to a code behind property in XAML

In Xamarin.Forms I would like to bind a code behind property to a label in XAML.
I found many answers and web pages about this topic, but they all cover more complex scenarios.
This is my XAML page:
<?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:TrackValigie"
x:Class="TrackValigie.SelViaggioPage">
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding ?????????}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
And this is code behind:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SelViaggioPage : ContentPage
{
private string _lblText;
public string LblText
{
get
{
return _lblText;
}
set
{
_lblText = value;
OnPropertyChanged();
}
}
public SelViaggioPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
this.LblText = "Ciao!!";
base.OnAppearing();
}
}
I would like to bind the "LblText" property to the label, using XAML only, that means without setting binding or binding context in code behind.
Is this possible?
your page will need to implement INotifyPropertyChanged, but the binding syntax should just be
<ContentPage x:Name="MyPage" ... />
...
<Label BindingContext="{x:Reference Name=MyPage}" Text="{Binding LblText}" />
Or if you don't want to swap the binding context for the entire control then use the following:
<?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:Name="this"
x:Class="SomePage">
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding SomeProp, Source={x:Reference this}}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Just add BindingContext = this; in code behind file.
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:TrackValigie"
x:Class="TrackValigie.SelViaggioPage">
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding LblText}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Code Behind
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SelViaggioPage : ContentPage
{
private string _lblText;
public string LblText
{
get
{
return _lblText;
}
set
{
_lblText = value;
OnPropertyChanged();
}
}
public SelViaggioPage()
{
InitializeComponent();
BindingContext = this;
}
protected override void OnAppearing()
{
base.OnAppearing();
this.LblText = "Ciao!!";
}
}
You need to set the x:Name for ContentPage as mentioned by Jason's Answer .
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TrackValigie"
x:Class="TrackValigie.SelViaggioPage"
x:Name = "MyControl"/>
Instead of using BindingContext, you can use ElementName
<TextBlock Text="{Binding ElementName=TestControl,Path=StudentName}"/>

Having issues displaying images Xamarin Forms using only C#

I ask this question with reference to this website https://developer.xamarin.com/guides/xamarin-forms/user-interface/images/#Local_Images
I tried the xaml code on the website and it works, however after I created a new xamarin PCL project and tested the c# code. It failed to display images.
What I did:
Removed everything from the AboutPage.xaml till it looks like this:
<?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="EmbbedImages.Views.AboutPage"
xmlns:vm="clr-namespace:EmbbedImages.ViewModels;"
Title="{Binding Title}">
<ContentPage.BindingContext>
<vm:AboutViewModel />
</ContentPage.BindingContext>
</ContentPage>
And then for the AboutPage.xaml.cs, I modified it such that it looks like the following:
using Xamarin.Forms;
namespace EmbbedImages.Views
{
public partial class AboutPage : ContentPage
{
public AboutPage()
{
InitializeComponent();
var beachImage = new Image { Aspect = Aspect.AspectFit };
beachImage.Source = ImageSource.FromFile("butterfly.jfif");
}
}
}
I have ensured that the butterfly.jfif image is added into my android drawable folder, however no images are being displayed. As I am new to xamarin and Android and c# any help would be greatly appreciated.
The image probably won't display, because it's not part of the Page.
If you've added it to the Page and it still won't show it would have to be a problem in loading / opening the file / decoding it.
Either you add it in XAML or edit your code to the following:
using Xamarin.Forms;
namespace EmbbedImages.Views
{
public partial class AboutPage : ContentPage
{
public AboutPage()
{
InitializeComponent();
var beachImage = new Image { Aspect = Aspect.AspectFit };
beachImage.Source = ImageSource.FromFile("butterfly.jfif");
this.Content = beachImage;
}
}
}
Adding it in XAML would look like that:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="EmbbedImages.Views.AboutPage"
xmlns:vm="clr-namespace:EmbbedImages.ViewModels;"
Title="{Binding Title}">
<ContentPage.BindingContext>
<vm:AboutViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<Image x:Name="beachImage" Aspect="AspectFit">
</ContentPage.Content>
</ContentPage>
And the code behind:
using Xamarin.Forms;
namespace EmbbedImages.Views
{
public partial class AboutPage : ContentPage
{
public AboutPage()
{
InitializeComponent();
beachImage.Source = ImageSource.FromFile("butterfly.jfif");
}
}
}

Categories