C# WPF MVVM已更新源,但未更新GUI

C# WPF MVVM已更新源,但未更新GUI,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在设计一个MVVM WPF应用程序,其中一个控件是这样的 <ListView Grid.Row="5" Margin="0,5,0,0" ItemsSource="{Binding temps, Mode=TwoWay}"/> 然后调用一个方法来更新Datadev的值。当我跟踪代码时,值会更改,但UI不会更新 public override CommResults ReadData() { channelselect = DataDevs.Count(

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

<ListView Grid.Row="5"  Margin="0,5,0,0" ItemsSource="{Binding temps, Mode=TwoWay}"/>
然后调用一个方法来更新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;
            }
        }
    }
public覆盖CommResults ReadData()
{
channelselect=DataDevs.Count(d=>d.isTest);
byte[]recvbuf=新字节[channelselect*2+7];
字节[]sendbuf=新字节[7];
sendbuf[0]=Convert.ToByte(moduleadr%256);
sendbuf[1]=0X07;
sendbuf[2]=0X07;
sendbuf[3]=BoolsToBytes()[0];
sendbuf[4]=0X00;
CommResults结果=GetCommData(sendbuf、recvbuf、channelselect*2+7);
if(result!=CommResults.OK)
{
返回结果;
}          
分析物a(recvbuf);
返回CommResults.OK;
}
专用void a(字节[]recvbuf)
{
对于(int i=0;ix.isTest).ToArray()[i].Value=(((256-recvbuf[i*2+6])*256-recvbuf[i*2+5])*0.0625);
}
else if(转换为32(ss)==0)
{
DataDevs.Where(x=>x.isTest).ToArray()[i].Value=((recvbuf[i*2+6]&7)*256+recvbuf[i*2+5])*0.0625;
}
}
}

很抱歉,缺少代码。

列表的类型更改为
可观察集合

public class IndicatorLightVM:DependencyObject
{
    /*---*/
    public ObservableCollection<DataDev> temps { get; set;}
    /*---*/
}
公共类指示符LightVM:DependencyObject
{
/*---*/
公共可观察收集时间{get;set;}
/*---*/
}
ObservableCollection
-表示动态数据收集,在添加、删除项目或刷新整个列表时提供通知

更新


您需要一个“自定义”
observateCollection
。这个问题可能与这个答案重复。要到达那里,您仍然需要和
observedcollection
。通过在那里实现答案,您将解决您的问题。

列表的类型更改为
可观察集合

public class IndicatorLightVM:DependencyObject
{
    /*---*/
    public ObservableCollection<DataDev> temps { get; set;}
    /*---*/
}
公共类指示符LightVM:DependencyObject
{
/*---*/
公共可观察收集时间{get;set;}
/*---*/
}
ObservableCollection
-表示动态数据收集,在添加、删除项目或刷新整个列表时提供通知

更新


您需要一个“自定义”
observateCollection
。这个问题可能与这个答案重复。要到达那里,您仍然需要和
observedcollection
。通过在那里实现答案,您将解决您的问题。

问题在于您没有在UI中直接使用

解决方案:

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

因此GUI不知道它必须在
Value
change时更新。WPF只有在知道GUI中正在使用的属性时才会对属性更改通知作出反应,而这不能通过
ToString
进行,只能通过
…Path=“PropertyName”
或以属性为目标的绑定进行操作。

问题是您没有在UI中直接使用

解决方案:

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

因此GUI不知道它必须在
Value
change时更新。WPF只有在知道GUI中正在使用的属性时才会对属性更改通知做出反应,而这不能通过
ToString
工作,只能通过
…Path=“PropertyName”
或以属性为目标的绑定来工作。

然后我调用一个方法更新Datadev的值。
它在哪里?请将代码添加到您的问题中。为什么您的“视图模型”源自
DependencyObject
?您更应该从实现INotifyPropertyChanged的抽象基类派生。您可能还需要为列表添加通知程序,以防与其他列表对象交换。UI如何访问
属性。我看不到
DisplayMemberPath
,所以我不知道您的
/*-*/
部分代码中是否有一个
ToString
重写…如果您创建一个。缺少很多详细信息。@grek40是的,我重写了ToString
,然后调用一个方法更新Datadev的值。
它在哪里?请将代码添加到您的问题中。为什么您的“视图模型”源自
DependencyObject
?您更应该从实现INotifyPropertyChanged的抽象基类派生。您可能还需要为列表添加通知程序,以防与其他列表对象交换。UI如何访问
属性。我看不到
DisplayMemberPath
,所以我不知道您的
/*-*/
部分代码中是否有一个
ToString
重写…如果您创建一个。缺少很多细节。@grek40是的,我覆盖了ToString,他没有添加或删除元素。他正在修改一个已经有通知程序的元素的内容。我已经尝试了ObservableCollection,但仍然不起作用。我认为当您从列表中删除/添加元素时,可以使用ObservableCollection。是的,我正在做Blacktempel说的。至少在链接问题中被接受的答案并没有真正解决这个问题。因此,如果你认为它是重复的,你应该提到哪个答案将是具体的解决方案。你是正确的@grek40,谢谢你指出它。对这个问题有帮助的答案是。因为这个答案提供了更新所有绑定的方法。他没有添加或删除元素。他正在修改一个已经有通知程序的元素的内容。我已经尝试了ObservableCollection,但仍然不起作用。我想当你移除
Value -> ToString -> GUI