I have a CollectionView layer that takes 2 variables. One of them should be updated dynamically, but I couldn’t figure out how to do it.
I am accessing ObservableCollection via ModelView and changing the value of the variable but it is not updating on the screen.
Thanks for helping.
Here is my sample code
<CollectionView x:Name="collectionview1" ItemsSource="{Binding PosesObserv}">
<CollectionView.ItemTemplate>
<DataTemplate>
<ContentView>
<StackLayout>
<Slider x:Name="slider" Minimum="0" Maximum="1" WidthRequest="100"></Slider>
<Label Text="{Binding Source={x:Reference slider}, Path=Value, StringFormat='[{0:0.00000}]'}"></Label>
<Label Text="{Binding poseValue}"></Label> // this value should be updated
</StackLayout>
</ContentView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
public partial class MainPage : ContentPage
{
PosesView pView = new PosesView();
public MainPage()
{
Task.Factory.StartNew(InitializeComponent);
BindingContext = pView;
Task.Factory.StartNew(StartListener);
}
public class Poses
{
private string _pose;
public string pose
{
get => _pose; set
{
_pose = value;
}
}
private double _poseValue;
public double poseValue
{
get => _poseValue; set
{
_poseValue = value;
}
}
}
public class PosesView : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Dictionary<string, double> posesDict = new() // There is lots of value
public PosesView()
{
_PosesObserv = getSliderC();
}
public List<Poses> poseList = new();
private ObservableCollection<Poses> getSliderC()
{
poseList.Clear();
foreach (KeyValuePair<string, double> entry in posesDict)
{
poseList.Add(new Poses { pose = entry.Key, poseValue = entry.Value });
}
ObservableCollection<Poses> poseCollection = new(poseList);
return poseCollection;
}
private ObservableCollection<Poses> _PosesObserv;
public ObservableCollection<Poses> PosesObserv
{
get => _PosesObserv;
set
{
if (_PosesObserv != value)
{
this._PosesObserv = value;
OnPropertyChanged();
}
}
}
public void OnPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
private void StartListener()
{
UdpClient udpListener = new(3001);
IPEndPoint ep = new(IPAddress.Parse("127.0.0.1"), 3001);
List<Poses> poseList = new();
try
{
while (true)
{
Thread.Sleep(1000);
byte[] bytes = udpListener.Receive(ref ep);
string[] s = Encoding.ASCII.GetString(bytes, 0, bytes.Length).Split("///");
string[] s1 = s.Skip(1).ToArray();
pView.PosesObserv.FirstOrDefault(i => i.pose == "ExamplePose").poseValue = Convert.ToDouble(s1[6]);
}
}
catch (SocketException e)
{
Debug.WriteLine(e);
}
finally
{
udpListener.Close();
}
}
}
>Solution :
Poses class needs to also implement INotfiyPropertyChanged, so that when you enter poseValue’s setter,
you can also call PropertyChanged.
Otherwise the Binding won’t be notified of a change in the property’s value.