通过 ViewModel 将数据网格绑定到模型集合

本文关键字:绑定 模型 集合 网格 数据网 ViewModel 数据 通过 | 更新日期: 2023-09-27 18:32:00

我是Caliburn.Micro的新手,但已经做了一些基本的WPF MVVM编程,所以知道这些概念。我倾向于以模型优先的样式进行开发,因此在将 WPF DataGrid绑定到Model中定义和更新的集合时出现问题。我应该如何最好地通过ViewModel View公开对Collection的引用,以便Model中的任何更新都通过ViewModel引用传播,而不必在ViewModel中连接?

Model

public class Market : PropertyChangedBase
{
    private string _MarketGroup;
    public string MarketGroup
    {
        get
        {
            return _MarketGroup;
        }
        set
        {
            if (_MarketGroup != value)
            {
                _MarketGroup = value;
                NotifyOfPropertyChange(() => MarketGroup);
            }
        }
    }
    private string _Expiry;
    public string Expiry
    {
        get
        {
            return _Expiry;
        }
        set
        {
            if (_Expiry != value)
            {
                _Expiry = value;
                NotifyOfPropertyChange(() => Expiry);
            }
        }
    }
    private string _MarketStatus;
    public string MarketStatus
    {
        get
        {
            return _MarketStatus;
        }
        set
        {
            if (_MarketStatus != value)
            {
                _MarketStatus = value;
                NotifyOfPropertyChange(() => MarketStatus);
            }
        }
    }
    private string _Epic;
    public string Epic
    {
        get
        {
            return _Epic;
        }
        set
        {
            if (_Epic != value)
            {
                _Epic = value;
                NotifyOfPropertyChange(() => Epic);
            }
        }
    }
    private string _InstrumentName;
    public string InstrumentName
    {
        get
        {
            return _InstrumentName;
        }
        set
        {
            if (_InstrumentName != value)
            {
                _InstrumentName = value;
                NotifyOfPropertyChange(() => InstrumentName);
            }
        }
    }
}
public interface IMarketService : InotifyPropertyChanged
{
    BindableCollection<Market> Markets {get;}
    void RefreshMarkets();
}
public class MarketService : PropertyChangedBase, IMarketService
{
    public MarketService()
    {
        Markets = new BindableCollection<IGMarket>();
    }
    private BindableCollection<Market> _Markets;
    public BindableCollection<Market> Markets
    {
        get
        {
            return _Markets;
        }
        private set
        {
            if (_Markets!= value)
            {
                _Markets = value;
                NotifyOfPropertyChange(() => Markets);
            }
        }
    }
    public void RefreshMarkets()
    {
        Markets.Clear();
        var markets = GetMarkets();
        foreach (var market in markets)
        {
            Markets.Add(market);
        }
    }
}

ViewModel

public class ShellViewModel : PropertyChangedBase
{
    private readonly IMarketService _MarketService;
    private readonly IAccountService _AccountService;
    public ShellViewModel(IMarketService marketService, IAccountService accountService)
    {
        _MarketService = marketService;
        _AccountService = accountService;
        Markets = new BindableCollection<IGMarket>(_MarketService.Markets);
    }
    public void Login()
    {
        Task.Run(() =>
        {
            if (_AccountService.Login())
            {
                LoggedIn = true;
                _MarketService.RefreshMarkets();
            }
        });
    }
    private BindableCollection<Market> _Markets;
    public BindableCollection<Market> Markets
    {
        get { return _Markets; }
        set
        {
            if (_Markets != value)
            {
                _Markets = value;
                NotifyOfPropertyChange(() => Markets);
            }
        }
    }
}

AccountServiceMarketService 都在AppBootsrapper中使用简单注入器作为 DI 框架注册为单例。

View

<DataGrid AutoGenerateColumns="False" ColumnWidth="*" HorizontalAlignment="Stretch" x:Name="Markets" Margin="0,0,0,0" CanUserAddRows="False" CanUserDeleteRows="False"  VerticalAlignment="Stretch" Height="auto" Width="auto" Grid.ColumnSpan="2">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding InstrumentName}" Header="Instrument Name" IsReadOnly="True"/>
        <DataGridTextColumn Binding="{Binding Expiry}" Header="Expiry" IsReadOnly="True"/>
        <DataGridTextColumn Binding="{Binding MarketGroup}" Header="Market Group" IsReadOnly="True"/>
        <DataGridTextColumn Binding="{Binding InstrumentType}" Header="Instrument Type" IsReadOnly="True"/>
        <DataGridTextColumn Binding="{Binding MarketStatus}" Header="Market Status" IsReadOnly="True"/>
    </DataGrid.Columns>
</DataGrid>

基本上没有任何东西出现在Grid上,即使_MarketService.Markets包含物品。如果可能的话,我想进行ViewViewModel响应Model BindableCollection的更改/更新?

谢谢。

通过 ViewModel 将数据网格绑定到模型集合

为什么要使用单独的Markets集合?常见的设计是使用

public BindableCollection<Market> Markets
{
    get { return _MarketService.Markets; }
    set
    {
        if (_MarketService.Markets != value)
        {
            _MarketService.Markets = value;
            NotifyOfPropertyChange(() => Markets);
        }
    }
}

现在您有两个单独的集合,一个在ShellViewModel.Markets中,一个在ShellViewModel.MarketService.Markets中,它们不引用内存中的相同引用或以任何方式同步。

您需要

datagrid绑定到BindableCollection

在 xaml ItemsSource={Binding Markets}中尝试此操作