Hi,
I have a form with ListView with customly rendered label on it (testzxing:CustomLabel). The listview's source is bound to ObservableCollection Items. "Process" contains 2 properties that determine what is supposed to be label's Text (Binding TimingVsPlan) and BgColor (Binding TimingBgColor). For some reason Text is displayed properly for all items, but the background color seems to be for all items the same as the first row. I've checked and both properties GET event is fired properly.. I think it might be related to late listview binding as bgColor is updated properly in some other form..
Here's some code:
XAML<ListView x:Name="lstProcesses" ItemsSource="{Binding Items}" ItemTapped="LstProcesses_ItemTapped" VerticalOptions="FillAndExpand" HasUnevenRows="True" SeparatorVisibility="Default" CachingStrategy="RecycleElement"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout Padding="10"> <Label Text="{Binding PlaceName}" LineBreakMode="WordWrap" Style="{DynamicResource ListItemTextStyle}" FontSize="Medium" FontAttributes="Bold"/> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="6*"/> <ColumnDefinition Width="4*"/> </Grid.ColumnDefinitions> <Label Text="{Binding SetName}" FontSize="Small" LineBreakMode="WordWrap" Style="{DynamicResource ListItemTextStyle}" Grid.Row="0" Grid.Column="0"/> <testzxing:CustomLabel Text="{Binding TimingVsPlan}" BgColor="{Binding TimingBgColor}" FontSize="Small" Grid.Row="0" Grid.Column="1"/> </Grid> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>
CODE BEHIND:public AssignedProcesses(AssignedProcessesViewModel vm) { InitializeComponent(); BindingContext = vm; }
VIEWMODEL:
public class AssignedProcessesViewModel : INotifyPropertyChanged
{
public AssignedProcessesViewModel() { } public async void Initialize() { ProcessKeeper keeper = new ProcessKeeper(); await keeper.GetUsersOpenProcesses("IsActive=false and IsFrozen=false"); if (keeper.Items.Any()) { //there are planned processes assigned to the user Items = new ObservableCollection<Process>(keeper.Items.OrderBy(i => i.PlannedStart)); WelcomeText = $"Poniżej znajduje się lista planowanych konserwacji w bieżącym okresie, które zostały przypisane min. do Ciebie. Liczba pozycji: {Items.Count}"; Display(); } } private ObservableCollection<Process> _Items { get; set; } public ObservableCollection<Process> Items { get { return _Items; } set { if(value != _Items) { _Items = value; OnPropertyChanged(); } } } private string _WelcomeText { get; set; } public string WelcomeText { get { return _WelcomeText; } set { if (value != _WelcomeText) { _WelcomeText = value; OnPropertyChanged(); } } } private bool _isWorking { get; set; } public bool IsWorking { get { return _isWorking; } set { if (_isWorking != value) { if (value == false) { if (PopupNavigation.Instance.PopupStack.Any()) { PopupNavigation.Instance.PopAllAsync(true); } // Hide loading screen } else { PopupNavigation.Instance.PushAsync(new LoadingScreen(), true); // Show loading screen } _isWorking = value; OnPropertyChanged(); } } } public void Display() { PopupNavigation.Instance.PushAsync(new AssignedProcesses(this), true); } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string name = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } }
PROCESS MODEL:
`public class Process : INotifyPropertyChanged
{
private Nullable _PlannedStart { get; set; }
public Nullable PlannedStart
{
get
{
return _PlannedStart;
}
set
{
if (value != _PlannedStart)
{
_PlannedStart = value;
OnPropertyChanged();
}
}
}
public Nullable PlannedFinish { get; set; }
public string TimingVsPlan { get { if (PlannedStart == null) { return "Nie dotyczy"; } else { if (PlannedStart < DateTime.Now.AddDays(-7)) { return "Zaległe"; } else { return "Bieżące"; } } } } public Color TimingBgColor { get { if (PlannedStart == null) { return Color.Default; } else { if (PlannedStart < DateTime.Now.AddDays(-7)) { return Color.Red; } else { return Color.Green; } } } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string name = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }}`
Answers
Your code looks no problem .
Does
CustomLabel
inherit from Label ?Why don't you use
BackgroundColor
instead ofBgColor
?In fact I just changed BgColor to BackgroundColor and it works as it should.. I used custom renderer to create BgProperty to have background with rounded edges. So probably, the problem is in my custom renderer..
`[assembly: ExportRenderer(typeof(CustomLabel), typeof(CustomLabelRendererAndroid))]
namespace TestZXing.Droid
{
public class CustomLabelRendererAndroid : LabelRenderer
{
public CustomLabelRendererAndroid(Context context) : base(context)
{
}`
Try to use
Effects
to implement rounded edges , it does not break the original background.Refer https://stackoverflow.com/a/52369634/8187800.