【问题标题】:Wpf DataGrid Only updates when clicking into CellWpf DataGrid 仅在单击单元格时更新
【发布时间】:2014-10-09 02:44:53
【问题描述】:

我正在放慢使用 Calburn 和 Rx 自学 WPF 的速度。

我当前的目标是将 DataGrid 绑定到“股票”集合,然后更新每只股票的价格并实时显示在我的视图中。最终我想使用 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);
        }
    }

}

【问题讨论】:

    标签: wpf mvvm datagrid inotifypropertychanged caliburn


    【解决方案1】:

    您很可能没有在 Stock 类上实现 INotifyPropertyChanged

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

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

    另一方面,无需在任何调度程序上调用 PerformUpdate,无论如何 Dispatcher.CurrentDispatcher 将为您提供同一线程的调度程序您正在执行,因此对其本身进行排队没有任何意义。

    while (true)
    {
        PerformUpdate(random);
    }
    

    【讨论】:

      猜你喜欢
      • 2015-05-05
      • 2012-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多