Я новичок в Caliburn.Micro, но проработал некоторое базовое программирование MVVM WPF, чтобы понять концепции. Я склонен развиваться в первом стиле модели и поэтому имеет проблему, связывающую WPF DataGrid
с коллекцией, определенной и обновленной в Model
. Как лучше всего предоставить ссылку на Collection
через ViewModel
на номер View
, чтобы любые обновления в Model
распространялись по ссылке ViewModel
, вместо того, чтобы подключаться к ViewModel
?Связать DataGrid с коллекцией моделей с помощью 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. на Grid
не появится
<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>
По существу ничего, даже если _MarketService.Markets
содержит элементы:
View
. Я хотел бы сделать View
и ViewModel
отвечать на изменения/обновления на Model
BindableCollection
, если это возможно?
Спасибо.
благодаря Rachel. Я уверен, что я попробовал это раньше, и это дало мне исключение потока, но теперь это работает! – percentum