我似乎有一个问题,DataGrid
通过接口本身添加行.以下是UI的屏幕截图:
如您所见,数据库中找到了0行,因此DataGrid
右侧没有显示任何内容.但是id就像那里有一个空行,用于手动添加行.该DataGrid.CanUserAddRows
设置为True
,但没有任何效果.这是xaml
为了DataGrid
,我已经冒昧地删除了一些代码,使其变小.
PrivilegeDetailsView.xaml
...
PrivilegeDetailsView.xaml.cs
public partial class PrivilegeDetailsView : IPrivilegeDetailsView { public PrivilegeDetailsView() { InitializeComponent(); } public DataGrid PrivilegesOnObjectsDataGrid { get { return PrivilegeDataGrid; } } public IViewModel ViewModel { get { return (IViewModel)DataContext; } set { DataContext = value; } } }
下面是ViewModel (VM)
对xaml
View
上面:
PrivilegeDetailsViewModel.cs
public class PrivilegeDetailsViewModel : ViewModelBase, IPrivilegeDetailsViewModel { private readonly IEventAggregator _eventAggregator; private readonly IPrivilegeViewModel _privilegeViewModel; private readonly IRoleHasPrivilegeOnObjectViewModelAdapterRepository _roleHasPrivilegeOnObjectViewModelAdapterRepository; private ObservableCollection_rolesHasPrivilegesOnObjects; public PrivilegeDetailsViewModel(IPrivilegeDetailsView view, IRoleHasPrivilegeOnObjectViewModelAdapterRepository roleHasPrivilegeOnObjectViewModelAdapterRepository, IPrivilegeViewModel privilegeViewModel, IEventAggregator eventAggregator) : base(view) { _roleHasPrivilegeOnObjectViewModelAdapterRepository = roleHasPrivilegeOnObjectViewModelAdapterRepository; _privilegeViewModel = privilegeViewModel; _eventAggregator = eventAggregator; Initialize(); } protected override sealed void Initialize() { _privilegeViewModel.PropertyChanged += PrivilegeViewModelOnPropertyChanged; _eventAggregator.GetEvent ().Subscribe(ToggleSelectPrivilege); ... } public new IPrivilegeDetailsView View { get { return (IPrivilegeDetailsView)base.View; } } public ObservableCollection RolesHasPrivilegesOnObjects { get { return _rolesHasPrivilegesOnObjects; } set { _rolesHasPrivilegesOnObjects = value; OnPropertyChanged(); } } public void Save() { if(RolesHasPrivilegesOnObjects == null) return; _roleHasPrivilegeOnObjectViewModelAdapterRepository.SaveChanges(RolesHasPrivilegesOnObjects); } private void ToggleExecutePrivilege(object obj) { var toggle = !View.PrivilegesOnObjectsDataGrid.SelectedItems.Cast () .All(x => x.HasExecute); foreach(var selectedItem in View.PrivilegesOnObjectsDataGrid .SelectedItems .Cast () .Where(selectedItem => selectedItem.Object .CanHavePrivilege("EXECUTE"))) { selectedItem.HasExecute = toggle; } } ... private void PrivilegeViewModelOnPropertyChanged(object s, PropertyChangedEventArgs e) { switch(e.PropertyName) { //When the SelectedSchema changes in the parent VM, I get the new rows to be shown in the DataGrid. case "SelectedSchema": RolesHasPrivilegesOnObjects = _roleHasPrivilegeOnObjectViewModelAdapterRepository .GetPrivilegesOnObjectsAssociatedWith((IRoleEntityViewModel)_privilegeViewModel.SelectedRole, (IContainerEntityViewModel)_privilegeViewModel.SelectedSchema); break; } } }
这是VM
对于每一行DataGrid
RoleHasPrivilegeOnObjectEntityViewModel.cs
public class RoleHasPrivilegeOnObjectEntityViewModel : EntityViewModelBase, IRoleHasPrivilegeOnObjectListItemViewModel { private readonly RoleHasPrivilegesOnObject _roleHasPrivilegesOnObject; public RoleHasPrivilegeOnObjectEntityViewModel(RoleHasPrivilegesOnObject roleHasPrivilegesOnObject) { _roleHasPrivilegesOnObject = roleHasPrivilegesOnObject; Role = new RoleEntityViewModel(_roleHasPrivilegesOnObject.Role); Object = new ObjectEntityViewModel(_roleHasPrivilegesOnObject.Object); } public override EntityType EntityType { get { return EntityType.NONE; } } public override RoleHasPrivilegesOnObject OriginalEntity { get { return _roleHasPrivilegesOnObject; } } public IRoleEntityViewModel Role { get; set; } public IObjectEntityViewModel Object { get; set; } public string ToolTip { get { return _roleHasPrivilegesOnObject.ToolTip; } } public bool HasExecute { get { return _roleHasPrivilegesOnObject.HasExecute; } set { _roleHasPrivilegesOnObject.HasExecute = value; OnPropertyChanged(); } } public bool CanHaveExecute { get { return _roleHasPrivilegesOnObject.CanHaveExecute; } } public override string Icon { get { return Object != null ? Object.Icon : string.Empty; } } public override string NAME { get { return _roleHasPrivilegesOnObject.NAME; } set { _roleHasPrivilegesOnObject.NAME = value; OnPropertyChanged(); } } ... }
我知道这是很多代码,我已经剥离了很多并放置了几个点(...)来表明存在更多的代码.注意:我使用EF5和PRISM
如何DataGrid
通过GUI接受新行?
我相信你的问题是使用ObservableCollection<IRoleHasPrivilegeOnObjectListItemViewModel>
的ItemsSource
.为了DataGrid
能够创建新行,必须有一个可以使用空构造函数构造的类型.
如果您将其更改为ObservableCollection<RoleHasPrivilegeOnObjectEntityViewModel>
相反,我很确定您的行将开始添加.
我最终做的是部分/大部分是Maverik所建议的.
我改为ObservableCollection<IRoleHasPrivilegeOnObjectListItemViewModel>
be ObservableCollection<RoleHasPrivilegeOnObjectEntityViewModel>
并创建了一个默认的构造函数,它以前没有.
那么问题是RoleHasPrivilegeOnObjectEntityViewModel
需要设置一些字段和属性才能运行,所以我创建了一个公共Initialize
函数来提供必要的参数.
我在事件中添加了一个事件处理程序DataGrid's
InitializingNewItem
,我调用了该Initialize
函数.
private void PrivilegesOnObjectsDataGridOnInitializingNewItem(object s, InitializingNewItemEventArgs e) { var newItem = e.NewItem as RoleHasPrivilegeOnObjectEntityViewModel; if (newItem == null) return; var role = _privilegeViewModel.SelectedRole; var schema = _privilegeViewModel.SelectedSchema; newItem.Initialize(role.OriginalEntity, schema.OriginalEntity); }
当试图添加一个新行时,点击ComboBox
没有触发InitializeNewItem
event
.但是点击任何其他列都会触发InitializeNewItem
event
,并且因为最初每个列Row's
VM
都有自己的AvailableObjectTypes
属性,ComboBox
ItemSource
如果ComboBox
在任何其他列之前选择了它,则不会设置,因此将其设置为空.
这是不是一个可以接受的行为让人感动AvailableObjectTypes
的PrivilegeDetailsViewModel
和不断变化的ComboBox's
ItemSource
,以这有助于绑定
ItemsSource="{Binding DataContext.AvailableObjectTypes, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"