2016-01-26 2 views
0

Я новичок в 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 отвечать на изменения/обновления на ModelBindableCollection, если это возможно?

Спасибо.

ответ

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, и они не ссылаясь на то же ссылки в памяти или синхронизируются каким-либо образом.

+0

благодаря Rachel. Я уверен, что я попробовал это раньше, и это дало мне исключение потока, но теперь это работает! – percentum

0

вы должны связать ваш datagrid на вашем BindableCollection

Попробуйте это в XAML ItemsSource={Binding Markets}

+0

благодарит за ваш ответ. у меня создалось впечатление, что для Caliburn.Micro использование соглашения «x: Name =« Рынки »« позаботится о привязке? – percentum

+0

Я так не думаю –

+1

@percentum Да, я думаю, что так работает Caliburn Micro. Он использует свойство 'Name' для создания общих привязок, поэтому, если DataGrid называется Markets, он создаст привязку для' DataGrid.ItemsSource' к '{Binding Markets}' – Rachel

Смежные вопросы