In a Maui XAML content page, I have a nested bindablelayout to generate a grid. Nothing comes up but when I during a debug session modify the XAML code it all shows up. What am I doing wrong here?
The XAML is pretty much just to bindablelayouts within each other. The first one is for each row, and the inner is for each cell on each row.
<ContentPage.Content>
<StackLayout BindableLayout.ItemsSource="{Binding Tiles}" Orientation="Vertical" >
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:PipeTileRowCollection">
<StackLayout BindableLayout.ItemsSource="{Binding}" Orientation="Horizontal" >
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:PipeTile">
<Border Stroke="Gray" StrokeThickness="1" Padding="0" StrokeShape="Rectangle">
<Image Source="{Binding ImageSrc}" HeightRequest="62" WidthRequest="62" ></Image>
</Border>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ContentPage.Content>
The C# is where I initialize the rows and columns. I started out with ObservableCollections then swithced to Lists. Eventually creating classes which inherit from List<> in order to be able to set proper x:Datatype in XAML. Neither of these changes helped.
public partial class MainPageModel : ObservableObject
{
public MainPageModel()
{
var rows = new PipeTileRowCollection();
for (int i = 0; i < 4; i++)
{
var cols = new PipeTileCollection();
for (int j = 0; j < 4; j++)
{
cols.Add(new PipeTile());
}
rows.Add(cols);
}
_Tiles = new PipeTileRowCollection(rows);
}
public ICommand TileTapCommand { get; set; }
[ObservableProperty]
private PipeTileRowCollection _Tiles;
}
public class PipeTileCollection : List<PipeTile>
{
}
public class PipeTileRowCollection : List<PipeTileCollection>
{
public PipeTileRowCollection()
{
}
public PipeTileRowCollection(PipeTileRowCollection rows) : base(rows)
{
}
}
The tile class is simple:
public partial class PipeTile : ObservableObject
{
public PipeTile()
{
_ImageSrc = ImageSource.FromFile("straight.png");
}
[ObservableProperty]
private ImageSource _ImageSrc;
}
And the page is simple as well:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new MainPageModel();
}
}
I have tried using ObservableCollection to no avail and also tried to add an initialize method called on appearing that initializes the lists but that didn't help.
Any help appreciated, Thanks!
In a Maui XAML content page, I have a nested bindablelayout to generate a grid. Nothing comes up but when I during a debug session modify the XAML code it all shows up. What am I doing wrong here?
The XAML is pretty much just to bindablelayouts within each other. The first one is for each row, and the inner is for each cell on each row.
<ContentPage.Content>
<StackLayout BindableLayout.ItemsSource="{Binding Tiles}" Orientation="Vertical" >
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:PipeTileRowCollection">
<StackLayout BindableLayout.ItemsSource="{Binding}" Orientation="Horizontal" >
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:PipeTile">
<Border Stroke="Gray" StrokeThickness="1" Padding="0" StrokeShape="Rectangle">
<Image Source="{Binding ImageSrc}" HeightRequest="62" WidthRequest="62" ></Image>
</Border>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ContentPage.Content>
The C# is where I initialize the rows and columns. I started out with ObservableCollections then swithced to Lists. Eventually creating classes which inherit from List<> in order to be able to set proper x:Datatype in XAML. Neither of these changes helped.
public partial class MainPageModel : ObservableObject
{
public MainPageModel()
{
var rows = new PipeTileRowCollection();
for (int i = 0; i < 4; i++)
{
var cols = new PipeTileCollection();
for (int j = 0; j < 4; j++)
{
cols.Add(new PipeTile());
}
rows.Add(cols);
}
_Tiles = new PipeTileRowCollection(rows);
}
public ICommand TileTapCommand { get; set; }
[ObservableProperty]
private PipeTileRowCollection _Tiles;
}
public class PipeTileCollection : List<PipeTile>
{
}
public class PipeTileRowCollection : List<PipeTileCollection>
{
public PipeTileRowCollection()
{
}
public PipeTileRowCollection(PipeTileRowCollection rows) : base(rows)
{
}
}
The tile class is simple:
public partial class PipeTile : ObservableObject
{
public PipeTile()
{
_ImageSrc = ImageSource.FromFile("straight.png");
}
[ObservableProperty]
private ImageSource _ImageSrc;
}
And the page is simple as well:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new MainPageModel();
}
}
I have tried using ObservableCollection to no avail and also tried to add an initialize method called on appearing that initializes the lists but that didn't help.
Any help appreciated, Thanks!
Share Improve this question asked Mar 23 at 21:40 Mr WMr W 6761 gold badge9 silver badges25 bronze badges 2 |2 Answers
Reset to default 0Firstly, please remove the _
for your properties, such as imageSrc
tiles
.No need to add _
before your property. Just write Lowercase property and CommunityToolkit.Mvvm will generate Upper property name automatically. By the way, you have create a new PipeTileRowCollection in MainPageModel constructor. no need to create a new PipeTileRowCollection after adding data like following code.
public partial class MainPageModel : ObservableObject
{
public MainPageModel()
{
Tiles = new PipeTileRowCollection();
for (int i = 0; i < 4; i++)
{
var cols = new PipeTileCollection();
for (int j = 0; j < 4; j++)
{
cols.Add(new PipeTile());
}
Tiles.Add(cols);
}
// _Tiles = new PipeTileRowCollection(rows);
}
public ICommand TileTapCommand { get; set; }
[ObservableProperty]
private PipeTileRowCollection tiles;
}
That is same for PipeTile, you can change the type of ImageSrc to string, Image can show it as well.
public partial class PipeTile : ObservableObject
{
public PipeTile()
{
ImageSrc = "straight.png";
}
[ObservableProperty]
private string imageSrc;
}
For your xaml layout. Please remove x:DataType="models:PipeTileRowCollection"
, you have binded Tiles(type is PipeTileRowCollection). No need to set DataType again.
<StackLayout BindableLayout.ItemsSource="{Binding Tiles}" Orientation="Vertical" Background="AliceBlue">
<BindableLayout.ItemTemplate>
<DataTemplate >
<StackLayout BindableLayout.ItemsSource="{Binding }" Orientation="Horizontal" >
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:PipeTile">
<Border Stroke="Gray" StrokeThickness="1" Padding="0" StrokeShape="Rectangle">
<Image Source="{Binding ImageSrc}" HeightRequest="62" WidthRequest="62" ></Image>
</Border>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
Ok finally got it to work by encapsulating the List<> into their own classes.
I also added all the previous suggestions for making the code prettier.
This is how it ended up:
<StackLayout BindableLayout.ItemsSource="{Binding Rows}" Orientation="Vertical" >
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:PipeTileCollection">
<StackLayout BindableLayout.ItemsSource="{Binding Columns}" Orientation="Horizontal" >
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="models:PipeTile">
<Border Stroke="Gray" StrokeThickness="1" Padding="0" StrokeShape="Rectangle">
<Image Source="{Binding ImageSrc}" HeightRequest="62" WidthRequest="62">
</Image>
</Border>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
and the C# code:
public partial class MainPageModel : ObservableObject
{
public MainPageModel()
{
Rows = new List<PipeTileCollection>();
for (int i = 0; i < 4; i++)
{
var row = new PipeTileCollection();
for (int j = 0; j < 4; j++)
{
row.Columns.Add(new PipeTile());
}
Rows.Add(row);
}
}
[ObservableProperty]
private List<PipeTileCollection> rows;
}
public partial class PipeTileCollection : ObservableObject
{
public PipeTileCollection()
{
Columns = new List<PipeTile>();
}
[ObservableProperty]
private List<PipeTile> columns;
}
public partial class PipeTile : ObservableObject
{
public PipeTile()
{
imageSrc = "straight.png";
}
[ObservableProperty]
private string imageSrc;
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744268426a4565978.html
when I during a debug session modify the XAML code it all shows up.
This sounds like a element display issue in XAML file. What element did you modify in the XAML file? – Guangyu Bai - MSFT Commented Mar 24 at 9:15