簡體   English   中英

使用事件聚集器在UserControls之間導航

[英]Navigate between UserControls with Event Aggegator

我有一個MainWindow,通過單擊菜單可以在UserControls之間導航,並且工作正常。

我正在使用以下模式:

https://rachel53461.wordpress.com/2011/05/08/simplemvvmexample/

在這些用戶控件之一中,有一個按鈕。 通過單擊此按鈕,我想導航到另一個用戶控件。

我怎么做?

的MainView

<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>

MainViewModel

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;
            }
        }
    }

SecondView

<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]和你的SecondViewModelPageViewModels[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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM