2017-09-04 66 views
0

我设计的MVVM WPF应用程序,以及控制装置的一个是这样的,WPF MVVM更新的源代码,但没有更新GUI

<ListView Grid.Row="5" Margin="0,5,0,0" ItemsSource="{Binding temps, Mode=TwoWay}"/> 

在视图模型,我有

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有一个DataDev列表作为属性,并且DataDev是

public abstract class DataDev: INotifyPropertyChanged 
{ 
    public int ModuleAddr { get; set; } 
    private double _value; 
    public double Value { 
     get 
     { 
      return _value; 
     } 
     set 
     { 
      _value = value; 
      OnPropertyChanged("Value"); 
     } 
    } 
/*---*/ 
} 

然后我调用一个方法更新Datadev的值。当我追踪代码时,值被更改,但UI不更新。

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; 
      } 
     } 
    } 

抱歉失踪码。

+0

'然后我调用一个方法来更新Datadev的值。“它在哪里?请将代码添加到您的问题中。 – Blacktempel

+0

为什么你的“视图模型”从“DependencyObject”派生?您应该从实现INotifyPropertyChanged的抽象基类派生。您可能还想为列表添加通告程序,以防与其他列表对象交换。 – Blacktempel

+0

UI如何访问“Value”属性。我没有看到'DisplayMemberPath',所以我不知道你是否在代码的'/ * --- * /'部分有一个'ToString'覆盖... – grek40

回答

4

问题是你不直接在你的用户界面中使用Value

解决方案:

<ListView 
    Grid.Row="5" 
    Margin="0,5,0,0" 
    ItemsSource="{Binding temps, Mode=TwoWay}" 
    DisplayMemberPath="Value"/> 

您当前的办法去以下路线:

Value -> ToString -> GUI 

所以GUI不知道它有对Value变化更新。当WPF只知道在GUI中使用的属性时,它只会对属性更改通知作出反应,并且该属性不通过ToString,但仅与...Path="PropertyName"或通过绑定锁定属性。

+0

神!谢谢!我被困了一天。非常感谢! – user2951219

-1

List的类型更改为ObservableCollection

public class IndicatorLightVM:DependencyObject 
{ 
    /*---*/ 
    public ObservableCollection<DataDev> temps { get; set;} 
    /*---*/ 
} 

ObservableCollection - 代表动态数据采集,提供通知,当项目将添加,删除,或当整个列表被刷新。

更新

你需要一个 “自定义” ObservableCollection。这个问题是这个SO答案的可能重复。要到达那里,您仍然需要和ObservableCollection。通过实施答案,您将解决您的问题。

+0

他没有添加或删除一个元素。他正在修改已经有通告者的元素的内容。 – Blacktempel

+0

我试过ObservableCollection,仍然没有工作。我认为ObservableCollection用于从列表中删除/添加元素。是的,我正在做Blacktempel所说的。 – user2951219

+1

至少在链接的SO问题中接受的答案并没有真正解决这个问题的问题。所以,如果你认为它是重复的,你应该提到哪个答案会成为解决方案。 – grek40