我想实现一些消息传递通信(我知道如何使用MVVM.Light的消息传递)但我认为我的情况比较棘手,因为我使用CommandParameter来更改ViewModel,我无法添加命令我想:x让代码变得更清晰。
XAML
<ListView x:Name="dataGrid" ItemsSource="{Binding Friends}" Height="314" BorderThickness="0" SelectedItem="{Binding SelectedItemFriends}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="Resources\Images\ic_status.png" Height="24" Width="18"/>
<StackPanel Margin="5" Orientation="Vertical">
<TextBlock FontWeight="Bold" Text="{Binding name}"/>
<StackPanel x:Name="RemoveItems" Margin="5" Orientation="Vertical">
<TextBlock Text="{Binding lastLocation}"/>
<TextBlock Text="{Binding timestamp}"/>
</StackPanel>
<StackPanel x:Name="AdditionItems" Margin="5" Orientation="Vertical" Visibility="Collapsed">
<TextBlock Text="{Binding Path=loc.area}"/>
<TextBlock Text="{Binding Path=loc.building}"/>
<TextBlock Text="{Binding Path=loc.floor}"/>
<TextBlock Text="{Binding Path=loc.room}"/>
</StackPanel>
</StackPanel>
<Button Style="{DynamicResource FlatButtonStyle}" Command="{Binding DataContext.SelectViewCommand, ElementName=GeneralWindowView}" CommandParameter="ChatViewModel" x:Name="button1" Content="Chat" Margin="10">
<Button.Template>
<ControlTemplate>
<Image Source="Resources\Images\chat_image.png"/>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" Value="true">
<Setter TargetName="AdditionItems" Property="Visibility" Value="Visible"/>
<Setter TargetName="RemoveItems" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
所以我在FriendsViewModel(是GeneralViewModel的孩子)中,我想将信息发送到ChatViewModel(也是GeneralViewModel的孩子)。问题是我可以在哪里发射命令?因为我正在使用命令参数,所以我无法实现其他命令:x并使用messenger。
提前致谢,
编辑:AViewModel
public abstract class AViewModel : ViewModelBase
{
//public WindowService ws;
public string Name { get; set; }
public RelayCommand<string> SelectViewCommand { get; set; }
public AViewModel()
{
//ws = new WindowService();
SelectViewCommand = new RelayCommand<string>(OnSelectViewCommand);
}
private static ObservableCollection<ViewModelBase> _ViewModels;
public static ObservableCollection<ViewModelBase> ViewModels
{
get { return _ViewModels; }
set { _ViewModels = value; }
}
public void AddViewModel(ViewModelBase viewmodel)
{
if (ViewModels == null)
ViewModels = new ObservableCollection<ViewModelBase>();
var currentVNs = (from vms in ViewModels where vms.InternalName == viewmodel.InternalName select vms).FirstOrDefault();
if (currentVNs == null)
ViewModels.Add(viewmodel);
}
public ViewModelBase GetViewModel(string viewmodel)
{
return ViewModels.FirstOrDefault(item => item.InternalName == viewmodel);
}
public ViewModelBase GetViewModelLogin(string viewmodel,object bla)
{
return ViewModels.FirstOrDefault(item => item.InternalName == viewmodel);
}
private void OnSelectViewCommand(string obj)
{
switch (obj)
{
case "ExitCommand":
Application.Current.Shutdown();
break;
default:
this.Current_ViewModel = this.GetViewModel(obj);
break;
}
}
private ViewModelBase _Current_ViewModel;
private IMessenger _messengerInstance;
public ViewModelBase Current_ViewModel
{
get { return _Current_ViewModel; }
set { _Current_ViewModel = value; OnPropertyChanged("Current_ViewModel"); }
}
protected IMessenger MessengerInstance
{
get
{
return this._messengerInstance ?? Messenger.Default;
}
set
{
this._messengerInstance = value;
}
}
}
答案 0 :(得分:0)
如果你记得在我上一次演示中,我在AviewModel的属性'Current_ViewModel'的setter中引发了一个'Event',每次你导航到另一个View时都会被触发。好吧,在考虑之后,我认为事件也可以发送一个对象[到新的ViewModel \ View] ....
你需要使用'CommandParameter'类...... ...
GetSecurityInfo(ph, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &desc)
示例用法...
public enum Command
{
None,
LogIn,
LogOut,
Recovery,
Register,
Exit
}
public class CommandParameter
{
public dynamic Obj { get; set; }
public Command Command { get; set; }
public string Link_1 { get; set; }
public string Link_2 { get; set; }
}
在上面的代码中
this.LogInCommandParameter = new CommandParameter() { Obj = this.CurrentUser, Command = Command.LogIn, Link_1 = "Main_ViewModel", Link_2 = "LogOnError_ViewModel" };
还有更多内容,所以我在这里添加了另一个演示http://www.mediafire.com/download/5ttjhuiuxex7eo1/Navigation1_25-05.rar(文件大小现在非常大,因为Demo使用EF而且还有一个Web服务......应该都可以工作来自VS IDE tho)
你会在AviewModel中看到
Obj = the object you want to send onto you next View
Command = is a 'hint' that you can Switch on in your Buttons bound Command
Link_1 & Link_2 are the Views that you want to Navigate too....
我现在正在筹集两个事件(DeActivate和Activate)并且还注意到我发送了一个名为SendObject的参数(这是你在CommandParameter中的Obj)...
在ViewModel中,你只需订阅像这样的事件......
private ViewModelBase _Current_ViewModel;
public ViewModelBase Current_ViewModel
{
get { return _Current_ViewModel; }
set {
if (Current_ViewModel != null)
Current_ViewModel.RaiseDeActivate(SendObject);
_Current_ViewModel = value;
if (Current_ViewModel != null)
Current_ViewModel.RaiseActivate(SendObject);
OnPropertyChanged("Current_ViewModel"); }
}
在演示代码中查看\步骤...您将看到(在创建新用户登录后)一旦您使用有效的UserName \ Password登录,即'User'(整个'User'Object'从LogOn_ViewModel传递到Main_ViewModel通过Base_ViewModel中的OnWindowCommand ...然后在Main_View上显示UserName(你曾经在LogOn_View中登录)。