[英]Navigate between UserControls with Event Aggegator
我有一個MainWindow,通過單擊菜單可以在UserControls之間導航,並且工作正常。
我正在使用以下模式:
https://rachel53461.wordpress.com/2011/05/08/simplemvvmexample/
在這些用戶控件之一中,有一個按鈕。 通過單擊此按鈕,我想導航到另一個用戶控件。
我怎么做?
<UserControl.Resources>
<DataTemplate DataType="{x:Type cvm:FirstViewModel}">
<cv:FirstView/>
</DataTemplate>
<DataTemplate DataType="{x:Type cvm:SecondViewModel}">
<cv:SecondView/>
</DataTemplate>
<cvm:MainViewModel x:Key="main"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource main}}">
<Border Grid.Row="0">
<Menu Height="58">
<ItemsControl ItemsSource="{Binding PageViewModels}" Width="289" Height="58">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<Hyperlink Command="{Binding ChangePageCommand, Mode=OneWay, Source={StaticResource main}}" CommandParameter="{Binding}" TextDecorations="{x:Null}">
<InlineUIContainer>
<TextBlock Text="{Binding Name}"/>
</InlineUIContainer>
</Hyperlink>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Menu>
</Border>
<Border Grid.Row="1" >
<ContentControl Content="{Binding CurrentUserControl}"/>
</Border>
</Grid>
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
PageViewModels.Add(new FirstViewModel());
PageViewModels.Add(new SecondViewModel());
// Set starting page
CurrentUserControl = PageViewModels[0];
}
#region Fields
private List<IUserContentViewModel> _pageViewModels;
public List<IUserContentViewModel> PageViewModels
{
get
{
if (_pageViewModels == null)
_pageViewModels = new List<IUserContentViewModel>();
return _pageViewModels;
}
}
private IUserContentViewModel _currentUserControl;
public IUserContentViewModel CurrentUserControl
{
get { return _currentUserControl; }
set
{
if (value != _currentUserControl)
{
_currentUserControl = value;
OnPropertyChanged("CurrentUserControl");
}
}
}
#region Methods
private void ChangeViewModel(IUserContentViewModel viewModel)
{
if (!PageViewModels.Contains(viewModel))
PageViewModels.Add(viewModel);
CurrentUserControl = PageViewModels
.FirstOrDefault(vm => vm == viewModel);
}
#endregion
private ICommand _changePageCommand;
#endregion
public ICommand ChangePageCommand
{
get
{
if (_changePageCommand == null)
{
_changePageCommand = new RelayCommand(
p => ChangeViewModel((IUserContentViewModel)p),
p => p is IUserContentViewModel);
}
return _changePageCommand;
}
}
}
<Grid Background="Blue">
<Button /> <!-- Going to ThirdView?????????-->
</Grid>
您必須從按鈕調用ChangePageCommand
:
<Button DataContext="{Binding Source={StaticResource main}}"
Command="{Binding ChangePageCommand"}
CommandParameter="{Binding PageViewModels[2]}">
我假設你有你的FirstViewModel
儲存在PageViewModels[0]
和你的SecondViewModel
在PageViewModels[1]
您還可以創建一個ThirdView
鏈接到你的ThirdViewModel
,因為你的另兩個瀏覽/的ViewModels:
<UserControl.Resources>
...
<DataTemplate DataType="{x:Type cvm:ThirdViewModel}">
<cv:ThirdView/>
</DataTemplate>
</UserControl.Resources>
就像一條建議一樣,您可以在代碼的開頭設置UserControl DataContext,而不是在任何UIElement(在您的情況下為Button和Grid)中使用它,如下所示:
<UserControl.DataContext>
<cvm:MainViewModel />
</UserControl.DataContext>
編輯>>>>
忘了說,您還必須將ThirdViewModel添加到PageViewModels集合中:
PageViewModels.Add(new ThirdViewModel());
我終於有了解決方案。
我將Event Aggregator與Prism 6一起使用。
首先,我創建一個Singleton。
internal sealed class ApplicationService
{
private ApplicationService() { }
private static readonly ApplicationService _instance = new ApplicationService();
internal static ApplicationService Instance { get { return _instance; } }
private IEventAggregator _eventAggregator;
internal IEventAggregator EventAggregator
{
get
{
if (_eventAggregator == null)
_eventAggregator = new EventAggregator();
return _eventAggregator;
}
}
}
然后是public class GoToThird : PubSubEvent<TEvent> { }
在MainViewModel
我訂閱了該事件並添加了ThirdViewModel()
。
public class MainViewModel : ViewModelBase
{
protected readonly IEventAggregator _eventAggregator;
public MainViewModel(IEventAggregator eventAggregator)
{
PageViewModels.Add(new FirstViewModel());
PageViewModels.Add(new SecondViewModel(ApplicationService.Instance.EventAggregator)));
PageViewModels.Add(new ThirdViewModel());
// Set starting page
CurrentUserControl = PageViewModels[0];
this._eventAggregator = eventAggregator;
}
private void GoToThird()
{
CurrentUserControl = PageViewModels[2];
}
}
最后,我在SecondViewModel()
發布了事件
public class SecondViewModel
{
protected readonly IEventAggregator _eventAggregator;
public SecondViewModel(IEventAggregator eventAggregator)
{
this._eventAggregator = eventAggregator;
}
private void Go()
{
_eventAggregator.GetEvent<GoToThird>().Publish();
}
private ICommand goToThirdCommand;
public ICommand GoToThirdCommand
{
get
{
return goToThirdCommand ?? (goToThirdCommand = new RelayCommand(p => this.Go(), p => this.CanGo()));
}
}
private bool CanGo()
{
return true;
}
}
非常感謝Rachel和Kirenenko
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.