通过 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);
}
}
}
}
AccountService
和 MarketService
都在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
包含物品。如果可能的话,我想进行View
并ViewModel
响应Model
BindableCollection
的更改/更新?
谢谢。
为什么要使用单独的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}
中尝试此操作