I'm designing an MVVM WPF app, and one of the controls is like this,
<ListView Grid.Row="5" Margin="0,5,0,0" ItemsSource="{Binding temps, Mode=TwoWay}"/>
In the ViewModel, I have
public class IndicatorLightVM:DependencyObject
{
/*---*/
public List<DataDev> temps { get; set;}
/*---*/
public IndicatorLightVM(IComm icomm, int moduleAddr = 1)
{
iComm = icomm;
pdm = new IndicatorLight(icomm, moduleAddr);
temps = pdm.DataDevs;
}
DataDevs has a list of DataDev as an attribute and DataDev is
public abstract class DataDev: INotifyPropertyChanged
{
public int ModuleAddr { get; set; }
private double _value;
public double Value {
get
{
return _value;
}
set
{
_value = value;
OnPropertyChanged("Value");
}
}
/*---*/
}
Then I call a method updating the Value of Datadev. When I tracked into the code, Values are changed but the UI is not updating.
public override CommResults ReadData()
{
channelselect = DataDevs.Count(d => d.isTest);
byte[] recvbuf = new byte[channelselect * 2+7];
byte[] sendbuf = new byte[7];
sendbuf[0] = Convert.ToByte(ModuleAddr % 256);
sendbuf[1] = 0X07;
sendbuf[2] = 0X07;
sendbuf[3] = BoolsToBytes()[0];
sendbuf[4] = 0X00;
CommResults result = GetCommData(sendbuf, recvbuf, channelselect * 2+7);
if (result != CommResults.OK)
{
return result;
}
AnalyseData(recvbuf);
return CommResults.OK;
}
private void AnalyseData(byte[] recvbuf)
{
for (int i = 0; i < channelselect; i++)
{
byte ss = Convert.ToByte(recvbuf[i * 2 + 6] & 0xF8);
if (Convert.ToInt32(ss) == 0xF8)
{
DataDevs.Where(x=>x.isTest).ToArray()[i].Value = (-((256 - recvbuf[i * 2 + 6]) * 256 - recvbuf[i * 2 + 5]) * 0.0625);
}
else if (Convert.ToInt32(ss) == 0)
{
DataDevs.Where(x => x.isTest).ToArray()[i].Value = ((recvbuf[i * 2 + 6] & 7) * 256 + recvbuf[i * 2 + 5]) * 0.0625;
}
}
}
Sorry for missing code.
The problem is you don't directly use the Value
in your UI.
Solution:
<ListView
Grid.Row="5"
Margin="0,5,0,0"
ItemsSource="{Binding temps, Mode=TwoWay}"
DisplayMemberPath="Value"/>
Your current approach goes the following route:
Value -> ToString -> GUI
So the GUI doesn't know it has to update on Value
change. WPF will only react to property change notifications when it is aware of the property being used in the GUI and that doesn't work via ToString
but only with ...Path="PropertyName"
or with Bindings targeting the property.
Change the type of the List
to an ObservableCollection
.
public class IndicatorLightVM:DependencyObject
{
/*---*/
public ObservableCollection<DataDev> temps { get; set;}
/*---*/
}
ObservableCollection
- Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
Update
You need a "custom" ObservableCollection
. This question is a possible duplicate of this SO answer. To get there you still need and ObservableCollection
. By implementing the answer there you'll solve your issue.
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.