First off, thankyou for the solution to my previous question here
That solution works very well, however, i'm struggling to bind the change of one of the properties. I have the BackgroundColour binding well when the UI loads with the following code: UI View
<StackLayout x:Name="stlShippingOrders" Spacing="5" Padding="0,0,0,5" >
<CollectionView Margin="0,-6,0,0" IsGrouped="True" ItemsSource="{Binding
ShippingItems}">
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<StackLayout Padding="5,-5,5,-5" Orientation="Horizontal"
BackgroundColor="LightBlue" HeightRequest="45">
<Label Text="{Binding Shipment.OrderCode}"
VerticalOptions="Center"/>
<Label Text="{Binding Shipment.CustomerName}"
VerticalOptions="Center"/>
<Label Text="{Binding Shipment.DeliveryDate}"
HorizontalOptions="EndAndExpand" VerticalOptions="Center" />
</StackLayout>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Padding="5,2,5,2" Text="{Binding ItemDescription}"
BackgroundColor="{Binding BackgroundColour}"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
ShippingItem Model (with added BacgroundColour property)
public class ShippingItem
{
public String ShippingItemId { get; set; }
public string ShippingItemScanCode { get; set; }
public string ItemDescription { get; set; }
public string ShippingOrderId { get; set; }
public bool IsLoaded { get; set; }
// Default set to transparent #00FFFFFF
public string BackgroundColour { get; set; } = "#00FFFFFF";
}
Class for grouping
public class ShippingItemGroup : ObservableCollection<ShippingItem>
{
public ShippingOrder Shipment { get; private set; }
public ShippingItemGroup(ShippingOrder shipment, ObservableCollection<ShippingItem>
shippingItems) : base(shippingItems)
{
Shipment = shipment;
}
}
ViewModel code that creates the group list and binds correctly
public ObservableCollection<ShippingItemGroup> ShippingItems {
get; private set; } = new ObservableCollection<ShippingItemGroup>();
foreach (var item in thisShipment.ShippingOrders)
{
ShippingItems.Add(new ShippingItemGroup(item,
item.ShippingItems));
}
ViewModel code that updates the list object when it is loaded. This is the bit i'm having trouble with, the shippingItem.BackgroundColour = "FFA533" changes the collection but doesn't update the UI.
foreach (ShippingItemGroup shippingItemGroup in ShippingItems)
{
foreach(ShippingItem shippingItem in
shippingItemGroup.Shipment.ShippingItems)
{
if(shippingItem.ShippingItemScanCode == scanCode)
{
shippingItem.IsLoaded = true;
shippingItem.BackgroundColour = "FFA533";
IsShipmentHeaderVisible = true;
IsShippingOrdersVisible = true;
IsErrorMessageVisible = false;
ScanCode = "";
}
}
}
As Jason mentioned in the comments, you need to implement INotifyPropertyChanged. This is the way I've done it for other projects. This is adapted from how MVVMCross does it.
First, create a base class where the INotifyPropertyChanged logic is setup:
public class ModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(storage, value))
{
return false;
}
storage = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
return true;
}
}
This will handle setting the value and firing the PropertyChanged event.
Next, have whatever model you need inherit from this base class. In this, it's your ShippingItem class:
public class ShippingItem : ModelBase
{
public int Id { get; set; }
public int ShippingOrderId { get; set; }
public string ItemDescription { get; set; }
public bool IsLoaded { get; set; }
private string backgroundColor;
public string BackgroundColor
{
get => backgroundColor;
set => SetProperty(ref backgroundColor, value);
}
}
Note the addition of the private backgroundColor field, and the custom setter that calls the SetProperty in the base class.
This will handle the updates for you.
I modified the code from the previous answer just as a proof of concept. This will update the colors every 1.5 seconds:
public MainPage()
{
InitializeComponent();
var shipment = new Shipment();
foreach (var item in shipment.ShippingOrders)
{
ShippingItems.Add(new ShippingItemGroup(item, item.ShippingItems));
}
BindingContext = this;
var rnd = new Random();
Task.Run(async () =>
{
while (true)
{
await Task.Delay(1500);
foreach (var shippingItemGroup in ShippingItems)
{
foreach (var shippingItem in shippingItemGroup)
{
shippingItem.BackgroundColor = Color.FromRgb(rnd.Next(256), rnd.Next(256), rnd.Next(256)).ToHex();
}
}
}
});
}
public ObservableCollection<ShippingItemGroup> ShippingItems { get; private set; } = new ObservableCollection<ShippingItemGroup>();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.