Reputation: 11
I have a .net maui app that displays a list in a CollectionView. Each entry in the collection is holds a grid with 4 columns and one row. Column 3 holds a label with the text bound to an observable property call "Locked" which is boolean. Column 4 holds a fixed image (of a lock), the IsVisible tag is bound to the same observable property. The relevant mark-up is as follows:
<CollectionView Grid.Row="2"
Grid.ColumnSpan="2"
ItemsSource="{Binding BridgeSessionsCollection}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="viewmodel:GridSession">
<SwipeView Margin ="2">
<SwipeView.RightItems>
<SwipeItem Text="Delete"
BackgroundColor="Red"
Command="{Binding Source={x:Reference BridgeRecordMainPage}, Path=BindingContext.RemoveSessionCommand}"
CommandParameter="{Binding ID}"/>
</SwipeView.RightItems>
<Frame Padding ="5,15" Margin="2" BorderColor="Black">
<Frame.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={x:Reference BridgeRecordMainPage},
Path=BindingContext.TapSessionCommand}"
CommandParameter="{Binding ID}"/>
</Frame.GestureRecognizers>
<Grid ColumnDefinitions=".1*, .7*, .1*, .1*">
<Label Grid.Column="0" Text="{Binding ID}"/>
<Label Grid.Column="1" Text="{Binding Name}"/>
<Label Grid.Column="2" Text="{Binding Locked}"/>
<Image IsVisible="{Binding Locked}"
HeightRequest="24"
Source="locked.png"
Grid.Column="3"
VerticalOptions="Start" />
</Grid>
</Frame>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
On entry to the application, the collection is displayed. I can see the value of the Locked property is true, however the image is not displayed.
If I run the app under windows and resize the widow the images appear. The application then works as expected. Resizing back to the initial size does not cause the issue to reappear.
Also, as can be seen above there is a TapGestureRecognizer which when selected transfers to a detail page for the selected row. When control returns to the main page from the detail page the images appear correctly - this works even if the main form is not resized so I don't think it's a situation of the image somehow not fitting in the column being resized.
When running on a locally connected iPhone the app displays the images correctly even on start up.
Appreciate any assistance.
EDIT To answer @toolmakerSteve comment below... The page is question is the first page loaded when he application starts ("MainPage.xaml"). It is linked to a ViewModel as follows..
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BridgeRecord.MainPage"
xmlns:viewmodel="clr-namespace:BridgeRecord.ViewModel"
x:DataType="viewmodel:MainPageViewModel"
x:Name="BridgeRecordMainPage">
and the collection is loaded in the constructor of the viewmodel as follows..
public MainPageViewModel()
{
BridgeSessionsCollection = new ObservableCollection<GridSession>();
BridgeApplicationData = BridgeDataModel.Get();
foreach (int id in BridgeApplicationData.BridgeSessionIDs.Values)
{
GridSession gs = new GridSession();
gs.ID = id;
BridgeSessionModel bs = BridgeSessionModel.Get(id);
gs.Name = bs.Name;
gs.Locked = bs.Locked;
BridgeSessionsCollection.Add(gs);
IDCount = Math.Max(IDCount, gs.ID);
}
}
Upvotes: 1
Views: 805
Reputation: 21462
Re "On entry to the application, the collection is displayed."
The exact sequence of initialization matters during startup.
This is on the first page you display, right?
Basically, something is not ready at the time the page layout is initialized from xaml. For a "good" fix, would need to see all the code that affects app startup, setting of bound variables, and layout of first page.
For now (if only as a test), here are two hacks, either of which might work-around the issue. BUT will cause page to be laid out and drawn again, which might be visually undesireable.
These should be run sometime after BridgeSessionsCollection
is set:
Work-around #1:
Dispatch.Dispatch(() =>
{
// Trigger event BindingContextChanged.
var holdBC = BindingContext;
BindingContext = null;
BindingContext = holdBC;
}
OR Work-around #2:
<CollectionView x:Name="theCollection" ... >
Dispatch.Dispatch(() =>
{
// Trigger redraw of all contents of the CollectionView named "theCollection".
var holdIS = theCollection.ItemsSource;
theCollection.ItemsSource = null;
theCollection.ItemsSource = holdIS;
}
If either of these correctly redraws, then a better fix could be proposed, given more complete source.
Upvotes: 0