Xamarin.Forms: UWP UI Binding errors that aren't real errors?

it-neX 1 Reputation point
2020-11-26T10:34:50.107+00:00

In my Xamarin.Forms app every ListView in UWP is rather slow in creating the cells, or entries, or rows, or whatever they're called. On Android and iOS the ListView scrolls as fast as you can make it go, but on UWP after a short fast scroll the list stays empty for a bit until the items are loaded in, in kind of a random order.

I've recently updated VS and Xamarin.Forms to the newest updates and stumbled upon the XAML-binding errors window. Here i found that in UWP I get multiple binding errors per cell which I think might hurt the scrolling performance of course. Then again I wonder, why do the cells show up completely fine then, if the binding throws errors? What exactly is wrong here? What can I do to get around these errors?

----------

Here some info:

This is one of the ListViews in my Application:
43033-uwplistviewerrors.png
(don't mind weird layout/format. This is fine.)

This is the XAML of the ListView:

<ListView coreevent:EventToCommand.FromEvent="ItemTapped"  
            coreevent:EventToCommand.ToCommand="{Binding ShowTaskDetailCommand}"  
            BackgroundColor="Transparent"  
            CachingStrategy="RecycleElement"  
            GroupDisplayBinding="{Binding GroupName}"  
            GroupShortNameBinding="{Binding GroupShortName}"  
            HasUnevenRows="true"  
            IsEnabled="{Binding IsBusy, Converter={StaticResource booleanNegationConverter}}"  
            IsGroupingEnabled="{Binding HasGroups}"  
            IsPullToRefreshEnabled="true"  
            IsRefreshing="{Binding IsBusy}"  
            ItemsSource="{Binding Path=TaskList}"  
            RefreshCommand="{Binding LoadTasksCommand}">  
    <ListView.GroupHeaderTemplate>  
        <DataTemplate>  
            <ViewCell>  
                <ViewCell.View>  
                    <StackLayout Padding="5" BackgroundColor="#8fafbc">  
                        <Label FontSize="Medium" Text="{Binding GroupName}" />  
                    </StackLayout>  
                </ViewCell.View>  
            </ViewCell>  
        </DataTemplate>  
    </ListView.GroupHeaderTemplate>  
    <ListView.ItemTemplate>  
        <DataTemplate>  
            <ViewCell>  
                <ViewCell.View>  
                    <Grid Style="{Binding IsSelected, Converter={StaticResource isSelectedStyleConverter}}">  
                        <Grid.RowDefinitions>  
                            <RowDefinition Height="*" />  
                            <RowDefinition Height="*" />  
                            <RowDefinition Height="*" />  
                            <RowDefinition Height="*" />  
                            <RowDefinition Height="1" />  
                        </Grid.RowDefinitions>  
                        <Grid.ColumnDefinitions>  
                            <ColumnDefinition Width="20" />  
                            <ColumnDefinition Width="*" />  
                            <ColumnDefinition Width="2*" />  
                            <ColumnDefinition Width="*" />  
                        </Grid.ColumnDefinitions>  
  
                        <BoxView Grid.Row="0"  
                                    Grid.RowSpan="5"  
                                    Grid.Column="0"  
                                    HorizontalOptions="FillAndExpand"  
                                    VerticalOptions="FillAndExpand"  
                                    Color="{Binding PriorityColor}" />  
  
                        <Label Grid.Row="0"  
                                Grid.Column="1"  
                                Style="{StaticResource listItemDataStyle}"  
                                TextColor="{Binding TextColor}"  
                                Text="{Binding Task.Word.WORKORDERNO}" />  
                        <Label Grid.Row="1"  
                                Grid.Column="1"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.Main.MAINTNO}"  
                                TextColor="{Binding TextColor}" />  
                        <Label Grid.Row="2"  
                                Grid.Column="1"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.Equi.EQUIPNO}"  
                                TextColor="{Binding TextColor}" />  
                        <Label Grid.Row="3"  
                                Grid.Column="1"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.Equi.INVENTORYNO}"  
                                TextColor="{Binding TextColor}" />  
  
                        <Label Grid.Row="0"  
                                Grid.Column="2"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.Word.SYS_FIRSTDAT, Converter={StaticResource dateTimeToStringConverter}}"  
                                TextColor="{Binding TextColor}" />  
                        <Label Grid.Row="1"  
                                Grid.Column="2"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.Main.MAINTNAME, Converter={StaticResource xmlConverter}}"  
                                TextColor="{Binding TextColor}" />  
                        <Label Grid.Row="2"  
                                Grid.Column="2"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.Equi.EQUIPDESC, Converter={StaticResource xmlConverter}}"  
                                TextColor="{Binding TextColor}" />  
                        <Label Grid.Row="3"  
                                Grid.Column="2"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.Equi.LOCATION, Converter={StaticResource xmlConverter}}"  
                                TextColor="{Binding TextColor}" />  
  
                        <Label Grid.Row="0"  
                                Grid.Column="3"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.GrpMain.MGROUPNAME, Converter={StaticResource xmlConverter}}"  
                                TextColor="{Binding TextColor}" />  
                        <Label Grid.Row="1"  
                                Grid.Column="3"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.Main.MAINTSTATION, Converter={StaticResource xmlConverter}}"  
                                TextColor="{Binding TextColor}" />  
                        <Label Grid.Row="2"  
                                Grid.Column="3"  
                                Style="{StaticResource listItemDataStyle}"  
                                Text="{Binding Task.Word.CANCELEDBY, Converter={StaticResource xmlConverter}}"  
                                TextColor="{Binding TextColor}" />  
  
                        <BoxView Grid.Row="4"  
                                    Grid.Column="0"  
                                    Grid.ColumnSpan="4"  
                                    Color="White" />  
                    </Grid>  
                </ViewCell.View>  
            </ViewCell>  
        </DataTemplate>  
    </ListView.ItemTemplate>  
</ListView>  

The TaskList property that this ListView is bound to is either contains TaskListItemViewModel objects:

public class TaskListItemViewModel : ViewModelBase  
{  
    public TaskListItemViewModel(TaskListItemNew taskItem)  
    {  
        Task = taskItem;  
    }  
  
    private TaskListItemNew _Task;  
    public TaskListItemNew Task  
    {  
        get  
        {  
            return _Task;  
        }  
        set { SetProperty(ref _Task, value); }  
    }  
  
    private bool _IsSelected;  
    public bool IsSelected  
    {  
        get  
        {  
            return _IsSelected;  
        }  
        set { SetProperty(ref _IsSelected, value); }  
    }  
  
    private Color _TextColor;  
    public Color TextColor  
    {  
        get  
        {  
            string temp = Task.Word.SYS_LOCKING;  
            if (string.IsNullOrWhiteSpace(temp))  
            {  
                if (Task.Word.MAINTTYPE == (uint)JobType.Breakdown)  
                {  
                    return Color.FromRgb(1, (128/255.0), (128/255.0));  
                }  
                else  
                {  
                    return Color.White;  
                }  
            }  
            else  
            {  
                return Color.FromRgb(1, (179/255.0), (102/255.0));  
            }  
        }  
        set { SetProperty(ref _TextColor, value); }  
    }  
  
    private Color _PriorityColor;  
    public Color PriorityColor  
    {  
        get  
        {  
            if (Task.Prio == null)  
            {  
                return Color.Default;  
            }  
            if (String.IsNullOrEmpty(Task.Prio.PRIORCOLOR))  
            {  
                return Color.Default;  
            }  
  
            var colorParts = Task.Prio.PRIORCOLOR.Split(',');  
            var colorIntParts = new int[4];  
            colorIntParts[0] = 255;  // Default Alpha Channel, in case it is missing in string data  
            for (int i = 0; i < colorParts.Length; i++)  
            {  
                int colPart = 0;  
                int.TryParse(colorParts[i], out colPart);  
                colorIntParts[i] = colPart;  
            }  
            return Color.FromRgba(colorIntParts[1], colorIntParts[2], colorIntParts[3], colorIntParts[0]);  
        }  
        set { SetProperty(ref _PriorityColor, value); }  
    }  
}  

Or Group<TaskListItemViewModel> objects:

public class Group<T> : List<T>  
{  
    private readonly Guid _ID;  
    public string GroupName { get; set; }  
    public string GroupShortName { get; set; }  
  
    public Group(string Name, string ShortName)  
    {  
        this._ID = Guid.NewGuid();  
        GroupName = Name;  
        GroupShortName = ShortName;  
    }  
  
    public override int GetHashCode()  
    {  
        return this._ID.GetHashCode();  
    }  
}  

The property TaskList is implemented in the ViewModel like this:

private IList _TaskList;  
public IList TaskList  
{  
    get => this._TaskList;  
    set => SetProperty(ref this._TaskList, value);  
}  

The ViewModel also inherits from ViewModelBase:

public abstract class ViewModelBase : IViewModel, IDisposable  
{  
    private string _title;  
    private bool _isBusy;  
  
    public string Title  
    {  
        get { return _title; }  
        set { SetProperty(ref _title, value); }  
    }  
  
    public bool IsBusy  
    {  
        get { return _isBusy; }  
        set { SetProperty(ref _isBusy, value); }  
    }  
  
    public event PropertyChangedEventHandler PropertyChanged;  
  
    protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)  
    {  
        if (object.Equals(storage, value)) return false;  
  
        storage = value;  
        OnPropertyChanged(propertyName);  
  
        return true;  
    }  
  
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)  
    {  
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));  
    }  
  
    protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression)  
    {  
        var propertyName = PropertySupport.ExtractPropertyName(propertyExpression);  
        OnPropertyChanged(propertyName);  
    }  
}  
      

All of this then results in these errors being thrown:
42953-uwplistviewerrors2.png
But as you can see above, the list still shows up as if everything is fine. I didn't even scroll yet.

42958-addinfouwp.txt

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,295 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,277 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Simon Dallmair 1 Reputation point
    2020-11-30T12:13:54.723+00:00

    This an old Bug. You get a binding error for each element in the list.

    https://github.com/xamarin/Xamarin.Forms/issues/10437

    0 comments No comments