我正在减慢与Calburn教授自己的WPF,然后希望Rx。
我目前的目标是将DataGrid绑定到“stock”的集合,然后更新每个股票的价格并让它实时显示在我的View中。最后我想用Rx做这个,但是现在我只是使用Wpf / Mvvm& Caliburn Micro。
但是,当我点击单个价格单元格而不是自动时,我的数据网格价格列仅显示更新的价格。谁能看到我做错了什么?
我的观点是:
<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);
}
}
}
答案 0 :(得分:0)
您很可能没有在课程库中实施 INotifyPropertyChanged
。
确保在设置任何属性时引发属性更改事件,以便刷新UI。
public double CurrentPrice
{
get
{
return currentPrice;
}
set
{
if (currentPrice != value)
{
currentPrice = value;
NotifyOfPropertyChange(() => CurrentPrice);
}
}
}
另外, 无需在任何调度程序上调用PerformUpdate ,无论如何 Dispatcher.CurrentDispatcher将为您提供相同线程的调度程序你正在执行所以排队它本身没有任何意义。
while (true)
{
PerformUpdate(random);
}