我是Caliburn.Micro的新手,但已经完成了一些基本的WPF MVVM编程,因此了解这些概念。我倾向于以模型第一种风格开发,因此将WPF DataGrid
绑定到Model
中定义和更新的集合时遇到问题。我应该如何最好地通过Collection
向ViewModel
公开对View
的引用,以便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);
}
}
}
}
使用Simple Injector作为DI框架, AccountService
和MarketService
都在AppBootsrapper
注册为单身。
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
的更改/更新?
感谢。
答案 0 :(得分:1)
为什么使用单独的Markets
集合?常见的设计是使用
public BindableCollection<Market> Markets
{
get { return _MarketService.Markets; }
set
{
if (_MarketService.Markets != value)
{
_MarketService.Markets = value;
NotifyOfPropertyChange(() => Markets);
}
}
}
现在你有两个独立的集合,一个在ShellViewModel.Markets
中,一个在ShellViewModel.MarketService.Markets
中,它们不是指内存中的相同引用或以任何方式同步。
答案 1 :(得分:0)
您需要在datagrid
BindableCollection
在你的xaml ItemsSource={Binding Markets}