就像this question一样,我正在使用the sample created by Josh Smith学习MVVM,我想添加更新功能。
出现两个问题(在提到的问题中没有解决):
答案 0 :(得分:3)
使用Josh的MvvmFoundation,您可以使用Messenger在ViewModels之间传递消息......
我会这样做:
-1。创建一个Messenger的单例实例,可以在应用程序的任何位置查看。
public class MyMessenger
{
static Messenger _messenger;
public static Messenger Messenger
{
get
{
if (_messenger == null)
_messenger = new Messenger();
return _messenger;
}
}
}
-2。然后在MainWindowViewModel中注册特定消息的通知 - 您可以轻松定义自己的消息类型,例如
MyMessenger.Messenger.Register<ViewModelBase>("CreateNew", (param) =>
{
DoWork(param); /* If memory serves, the MainWindowViewModel already has the logic to create a new CustomerViewModel and put it in your Workspaces collection... (which I think answers your second point) */
});
-3。最后,您需要在原始ViewModel中“通知”此消息,
简单地:
MyMessenger.Messenger.NotifyColleagues("CreateNew", new CustomerViewModel(customerNo));
抱歉 - 我不记得CustomerViewModel的确切结构,但我希望你明白这一点:)
希望这会有所帮助:) 伊恩
答案 1 :(得分:3)
这里有很多事情要发生。你的问题有两个部分(如果我没有遗漏任何东西)。
如何对ListViewItem进行DoubleClick,MVVM样式
有很多方法,但是SO上的这个问题总结得很好: Firing a double click event from a WPF ListView item using MVVM
我个人使用MarlonGrech的附加行为,所以我会告诉你如何做到这一点:
<ListView
AlternationCount="2"
DataContext="{StaticResource CustomerGroups}"
...>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="acb:CommandBehavior.Event"
Value="MouseDoubleClick" />
<Setter Property="acb:CommandBehavior.Command"
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}, Path=DataContext.EditCustomerCommand}" />
<Setter Property="acb:CommandBehavior.CommandParameter"
Value="{Binding}" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
这将绑定到您需要在AllCustomersViewModel中设置的EditCustomerCommand(这将是一个RelayCommand)。
添加新工作区
这个更棘手。您会注意到MainWindowViewModel有一个AddWorkspace,但我们实际上没有从AllCustomersViewModel引用该ViewModel。
我决定(对我而言)最好的方法是创建另一个名为“IWorkspaceCommands”的接口,AllCustomersViewModel将用它来创建新的工作区。这主要是与之前的回答者对Messenger方法的建议形成对比。如果你更喜欢Messenger方法,你可以在这里使用它。
MainWindowViewModel实际上会实现它,并在创建AllCustomersViewModel时自行传递。
public interface IWorkspaceCommands
{
void AddWorkspace(WorkspaceViewModel view);
}
这是界面的基本实现。 这包括根据要求检查视图是否已打开(非常简单!):
#region IWorkspaceCommands Members
public void AddWorkspace(WorkspaceViewModel view)
{
if (!Workspaces.Contains(view))
{
Workspaces.Add(view);
}
SetActiveWorkspace(view);
}
#endregion
最后,这是我在你的AllCustomersViewModel中告诉你的RelayCommand(以及一些构造函数修改):
IWorkspaceCommands _wsCommands;
public AllCustomersViewModel(CustomerRepository customerRepository, IWorkspaceCommands wsCommands)
{
_wsCommands = wsCommands;
EditCustomerCommand = new RelayCommand(EditCustomer);
...
}
public void EditCustomer(object customer)
{
CustomerViewModel customerVM = customer as CustomerViewModel;
_wsCommands.AddWorkspace(customerVM);
}
这就是它。因为您正在处理对用于创建AllCustomersViewModel的相同ViewModel的引用,所以当您在一个屏幕中编辑它时,它会在另一个屏幕中更新,而不会发生事件或消息传递(很好!,但可能不够健壮)。
ComboBox没有自动选择公司/人的价值,但这仍然存在问题,但这仍然是读者的练习。
作为今天我的套餐的一部分,我包括一个功能齐全的演示,无需额外费用。 http://dl.getdropbox.com/u/376992/MvvmDemoApp.zip
希望这有帮助,
安德森