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

왜 "View-Model"이'DependencyObject'에서 파생 되었습니까? INotifyPropertyChanged를 구현하는 추상 기본 클래스에서 파생되어야합니다. 다른 목록 개체와 교환 할 경우에 대비하여 목록에 알리미를 추가 할 수도 있습니다. – Blacktempel

+0

UI가 'Value'속성에 어떻게 액세스합니까? 'DisplayMemberPath'가 보이지 않기 때문에'/ * --- * /'코드 부분에'ToString' 오버라이드가 있는지 모르겠습니다 ... – grek40

답변

4

사용자의 UI에 Value을 직접 사용하지 않는 것이 문제입니다.

솔루션 :

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

현재 접근 방식은 다음과 같은 경로를 간다 :

Value -> ToString -> GUI 

는 그래서 GUI는이 Value 변화를 업데이트해야 알 수 없습니다. WPF는 GUI에서 사용중인 속성을 인식하고 을 통해 작동하지 않고 ...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은 목록에서 요소를 제거/추가 할 때 사용되는 것으로 생각했습니다. 네, 블랙 템펠이 한 일을하고 있어요. – user2951219

+1

연결된 SO 질문에서 적어도 받아 들인 대답은 실제로이 질문의 문제를 다루지 않습니다. 그래서 당신이 그것의 복제본을 생각한다면, 어떤 해결책이 구체적으로 해결책이 될지 언급해야합니다. – grek40