WPF MVVM更新了源但未更新GUI

时间:2017-09-04 05:53:38

标签: c# wpf mvvm

我正在设计一个MVVM WPF应用程序,其中一个控件是这样的,

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

在ViewModel中,我有

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

很抱歉找不到代码。

2 个答案:

答案 0 :(得分: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"或针对该属性的Bindings。< / p>

答案 1 :(得分:-1)

List的类型更改为ObservableCollection

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

ObservableCollection - 表示动态数据集合,在添加,删除项目或刷新整个列表时提供通知。

<强>更新

你需要一个&#34; custom&#34; ObservableCollection。这个问题可能与此SO答案重复。为了达到目的,你仍然需要ObservableCollection。通过实施答案,您将解决您的问题。