2017-09-04 42 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