Wpf DataGrid仅在单击单元格时更新

Wpf DataGrid仅在单击单元格时更新,wpf,mvvm,datagrid,inotifypropertychanged,caliburn,Wpf,Mvvm,Datagrid,Inotifypropertychanged,Caliburn,我正在慢慢地用Calburn教自己WPF,然后希望是Rx 我目前的目标是将DataGrid绑定到“股票”集合,然后更新每个股票的价格,并让它实时显示在我的视图中。最终,我希望使用Rx来实现这一点,但现在我只使用Wpf/Mvvm和Caliburn Micro 但是,当我单击单个价格单元格时,datagrid的价格列仅显示更新后的价格,而不是自动显示。谁能看出我做错了什么 我的看法是: <Window x:Class="StockPriceSim.Views.MainView" xml

我正在慢慢地用Calburn教自己WPF,然后希望是Rx

我目前的目标是将DataGrid绑定到“股票”集合,然后更新每个股票的价格,并让它实时显示在我的视图中。最终,我希望使用Rx来实现这一点,但现在我只使用Wpf/Mvvm和Caliburn Micro

但是,当我单击单个价格单元格时,datagrid的价格列仅显示更新后的价格,而不是自动显示。谁能看出我做错了什么

我的看法是:

<Window x:Class="StockPriceSim.Views.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:model="clr-namespace:StockPriceSim.ViewModels"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:viewModels="clr-namespace:StockPriceSim.ViewModels"
    mc:Ignorable="d"
    d:DataContext="{x:Type viewModels:MainViewModel}">
<StackPanel>
    <DataGrid x:Name="Stocks" ItemsSource="{Binding Stocks, Mode=OneWay,     NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"  />
</StackPanel>
</Window>

我的视图模型是:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using Caliburn.Micro;
using StockPriceSim.Model;

namespace StockPriceSim.ViewModels
{
    public class MainViewModel : PropertyChangedBase
    {
        public MainViewModel()
        {
            var initialData = new List<Stock>();

            initialData.Add(new Stock {CurrencyCode = "GBP", CurrentPrice = 102.11, Id = 1, LongName = "BP Long Name", ShortName = "BPP"});
            initialData.Add(new Stock { CurrencyCode = "GBP", CurrentPrice = 99.99, Id = 2, LongName = "RBS Long Name", ShortName = "RBS" });
            initialData.Add(new Stock { CurrencyCode = "EUR", CurrentPrice = 97.00, Id = 3, LongName = "BNPP LongName", ShortName = "BNP" });
            initialData.Add(new Stock { CurrencyCode = "EUR", CurrentPrice = 112.15, Id = 4, LongName = "Deutsche Long Name", ShortName = "DSH" });
            initialData.Add(new Stock { CurrencyCode = "USD", CurrentPrice = 98.25, Id = 5, LongName = "General Motors", ShortName = "GMM" });
            initialData.Add(new Stock { CurrencyCode = "USD", CurrentPrice = 131.12, Id = 6, LongName = "Microsfot", ShortName = "MSF" });
            initialData.Add(new Stock { CurrencyCode = "EUR", CurrentPrice = 95.66, Id = 7, LongName = "Santandar", ShortName = "SDT" });
            initialData.Add(new Stock { CurrencyCode = "CAD", CurrentPrice = 104.56, Id = 8, LongName = "Royal Mounties", ShortName = "RYM" });
            initialData.Add(new Stock { CurrencyCode = "ZAR", CurrentPrice = 103.29, Id = 9, LongName = "Standard Long Name", ShortName = "STF" });

            Stocks = new ObservableCollection<Stock>(initialData);

            Task.Run(() => UpdateStocks());
        }

        private ObservableCollection<Stock> _stocks;

        public ObservableCollection<Stock> Stocks
        {
            get { return _stocks; }
            set
            {
                _stocks = value;
                NotifyOfPropertyChange(() => Stocks);
            }
        }

        private void UpdateStocks()
        {
            var random = new Random();

            while (true)
            {
                Dispatcher.CurrentDispatcher.Invoke(() => PerformUpdate(random));
            }
        }

        private void PerformUpdate(Random random)
        {
            foreach (var stock in Stocks)
            {
                double next = random.NextDouble()*(110.0 - 90.0) + 90.0;

                stock.CurrentPrice = next;                
            }

            Thread.Sleep(2000);
        }
    }
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows.Threading;
使用Caliburn.Micro;
采用股票价格模拟模型;
命名空间StockPriceSim.ViewModels
{
公共类MainViewModel:PropertyChangedBase
{
公共主视图模型()
{
var initialData=新列表();
initialData.Add(新股票{CurrencyCode=“GBP”,CurrentPrice=102.11,Id=1,LongName=“BP Long Name”,ShortName=“BPP”});
initialData.Add(新股票{CurrencyCode=“GBP”,CurrentPrice=99.99,Id=2,LongName=“RBS Long Name”,ShortName=“RBS”});
initialData.Add(新股{CurrencyCode=“EUR”,CurrentPrice=97.00,Id=3,LongName=“BNP LongName”,ShortName=“BNP”});
initialData.Add(新股票{CurrencyCode=“EUR”,CurrentPrice=112.15,Id=4,LongName=“Deutsche Long Name”,ShortName=“DSH”});
initialData.Add(新股票{CurrencyCode=“USD”,CurrentPrice=98.25,Id=5,LongName=“通用汽车”,ShortName=“GMM”});
initialData.Add(新股{CurrencyCode=“USD”,CurrentPrice=131.12,Id=6,LongName=“Microsfot”,ShortName=“MSF”});
initialData.Add(新股票{CurrencyCode=“EUR”,CurrentPrice=95.66,Id=7,LongName=“Santandar”,ShortName=“SDT”});
initialData.Add(新股票{CurrencyCode=“CAD”,CurrentPrice=104.56,Id=8,LongName=“Royal Mounties”,ShortName=“RYM”});
initialData.Add(新股{CurrencyCode=“ZAR”,CurrentPrice=103.29,Id=9,LongName=“标准长名”,ShortName=“STF”});
股票=新的可观察集合(初始数据);
运行(()=>UpdateStocks());
}
私人可观测集合股票;
公开募股
{
获取{return\u stocks;}
设置
{
_股票=价值;
财产变动通知(()=>股票);
}
}
私有void UpdateStocks()
{
var random=新的random();
while(true)
{
Dispatcher.CurrentDispatcher.Invoke(()=>PerformUpdate(random));
}
}
专用无效性能更新(随机)
{
foreach(var存量)
{
double-next=random.NextDouble()*(110.0-90.0)+90.0;
stock.CurrentPrice=next;
}
《睡眠》(2000年);
}
}

}

最有可能的情况是,您没有在类股票上实现InotifyProperty更改

确保在设置任何属性时引发属性更改事件,以便刷新UI

public double CurrentPrice
{
    get
    { 
        return currentPrice;
    }
    set
    {
        if (currentPrice != value)
        {
            currentPrice = value;
            NotifyOfPropertyChange(() => CurrentPrice);
        }
    }
}

另一方面,不无需在任何调度程序上调用PerformUpdate,而且无论如何,dispatcher.CurrentDispatcher将为您获取与您正在执行的线程相同的调度程序,因此对其本身进行排队没有任何意义

while (true)
{
    PerformUpdate(random);
}