代码之家  ›  专栏  ›  技术社区  ›  percentum

通过ViewModel将DataGrid绑定到模型集合

  •  0
  • percentum  · 技术社区  · 9 年前

    我是新来卡利本的。Micro,但已经做了一些基本的WPF MVVM编程,因此了解这些概念。我倾向于以模型优先的风格开发,因此绑定WPF时会出现问题 DataGrid 到在中定义和更新的集合 Model 。我应该如何最好地公开对 Collection 通过 ViewModel View ,以便 模型 通过 视图模型 参考,而不必在 视图模型 ?

    模型 :

    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);
            }
        }
    }
    

    视图模型 :

    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 使用Simple Injector作为DI框架。

    看法 :

    <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 包含个项目。我想做 看法 视图模型 响应对的更改/更新 模型 BindableCollection 如果可能的话?

    谢谢

    2 回复  |  直到 9 年前
        1
  •  1
  •   Rachel    9 年前

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

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

    现在你有两个独立的收藏,一个在 ShellViewModel.Markets 一个在 ShellViewModel.MarketService.Markets ,并且它们没有引用内存中的相同引用,也没有以任何方式进行同步。

        2
  •  0
  •   A.Caillet    9 年前

    你需要把你的 datagrid 在您的 BindableCollection

    在xaml中试试这个 ItemsSource={Binding Markets}