【发布时间】:2016-10-18 09:58:10
【问题描述】:
我正在做一个项目,其中主窗口有 4 个视图。其中有两种观点让我很烦恼。
It helps to think of the project as something like MS Outlook, where you have a list on the left and, when one entry is selected, the right pane shows the details of that view.
不过,我的项目将有多个 MyList。因此,就像在 MS Word 中一样,您一直在打开和编辑新文档,因此用户也会在其中浏览多个 MyList。
当前发生的情况是,左窗格中的选定条目显示在右窗格中,但 单击后有一个选择。所以第一次选择什么都不显示,下一次选择显示之前选择的项目,下一个显示之前选择的项目,等等。
我正在使用 Prism 6。我还使用名为 ObservableImmutableList 而不是 ObservableCollection 的 this library 来处理我的视图的 Listview 对象。
相关代码:
我的列表视图模型:
public class MyListViewModel : BindableBase
{
private MyListModel activeMyList;
private IEventAggregator _eventAggregator;
public MyListViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_selectItemDelegateCommand = DelegateCommand<IList>.FromAsyncHandler(selectItem);
//Simplified version of real method
activeList = MyListModel.MyList.GetActiveListItem(_eventAggregator);
...
}
private DelegateCommand<System.Collections.IList> _selectItemDelegateCommand;
/// <summary>
/// Command associated with the selection of an item in the observableimmutablelist
/// </summary>
public DelegateCommand<System.Collections.IList> SelectItemDelegateCommand
{
get
{
return _selectItemDelegateCommand;
}
private set { _selectItemDelegateCommand = value; }
}
private async Task<int> selectItem(System.Collections.IList items)
{
var id = items.Cast<MyListItemViewModel>();
_eventAggregator.GetEvent<ItemUpdateEvent>().Publish(MyListItems.FirstOrDefault(x => x.ItemID == id.First<MyListItemViewModel>().ID).toAbstractRepresentation());
return await Task.FromResult(1);
}
private readonly object _myListItemsLock;
private ObservableImmutableList<MyListItemViewModel> _myListItems;
public ObservableImmutableList<MyListItemViewModel> MyListItems
{
get { return _myListItems; }
private set
{
lock (_myListItemsLock)
{
SetProperty(ref _myListItems, value);
}
}
}
}
此外,我有一个单独的 ViewModel,称为 ActiveMyListItem,视图绑定到它。它订阅了 eventtaggregator
相关代码:
public ActiveMyListItemViewModel(IEventAggregator eventAgg) : BindableBase
{
if (_eventAggregator == null && eventAgg != null)
{
_eventAggregator = eventAgg;
_eventAggregator.GetEvent<ItemUpdateEvent>().Subscribe(setProperties);
}
}
protected void setProperties(AbstractRepresentation abstract)
{
try
{
setProperties(abstract.ID, abstract.name, [...]);
}
catch (NullReferenceException nre)
{
throw nre;
}
}
如果还有什么需要我提供的,请告诉我。干杯!
编辑
我想澄清一下,MyListViewModel 中的属性 MyListItems 是由一个名为 MyListItemViewModel 的类组成的。所选项目使用名为 ActiveListItemViewModel 的视图模型。
在我的代码 sn-p 中,我没有显示这个,但在实际代码中,它们都继承自一个基类,因为它们有很多相似的特性。反过来,基类继承自 BindableBase。
我不确定这是否是问题的一部分,所以把它放在那里。
更新
所以我能够确定问题所在。在我的基类视图模型中,属性代码如下所示
protected String _txtDocName;
public String TxtDocName
{
get { return _myModelItem.Name; }
set
{
SetProperty(ref _txtDocName, value);
_myModelItem.Name = _txtDocName;
}
}
将其更改为这样可以立即工作。
protected String _txtDocName;
public String TxtDocName
{
get { return _myModelItem.Name; }
set
{
_txtDocName = value;
_myModelItem.Name = value;
OnPropertyChanged("TxtDocName");
}
}
但是,这太笨重了,并且会消除 Prism 所做的大量工作。有什么更好的方法来解决这个问题?
【问题讨论】:
-
创建区域视图X.当列表框选择是使用Prism IregionManager.RequestNavigate到其他视图时。 span>
-
非常感谢您的回复。条目详细信息视图始终可见。我没有导航到它,我只是填充它。为什么要使用 RegionManager Navigate 命令?
-
为什么 selectItems 是异步的?
-
主要是因为我最初在早期版本的代码中从其他地方获取了 AbstractRepresentation。但是,我确实在没有 async await 功能的情况下测试了代码,并且它的行为方式完全相同。
-
您能否在一个小示例项目中重现该问题?还要记住在 cmets 中提及用户名,以便用户收到通知。例如:如果您想通知我某事,只需使用@Vishal,然后输入您的评论。这将通知我您已回复我。
标签: c# wpf mvvm async-await prism