簡體   English   中英

更改視圖Wpf MVVM

[英]Changing View Wpf MVVM

我是WPF和MVVM的初學者,但想通過構建一些小項目來學習它。
我有一個基於Rachel Lim示例的使用Model-View-ViewModel模式的WPF應用程序。 在我的應用程序中,我有2個視圖-EmployeesList和EmployeeDetails。 員工列表存儲在GidView中。

我的主要問題是

  • 雙擊行時如何更改視圖,
  • 如何從第一列(employee_id)中獲取值並將其傳遞到EmployeeDetails視圖。

基本導航在帶有DataTmplate和ItmCntrol的xaml中:

<Window.Resources>
    <DataTemplate DataType="{x:Type local:HomeViewModel}">
        <local:HomeView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:EmployeesListViewModel}">
        <local:EmployeesListView />
    </DataTemplate>
</Window.Resources>



<ItemsControl ItemsSource="{Binding PageViewModels}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding Name}"
                    Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                    CommandParameter="{Binding }"
                    Margin="2,5"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我也有ApplicationViewModel在哪里視圖列表

public class ApplicationViewModel : ObservableObject
{
    #region Fields

    private ICommand _changePageCommand;

    private IPageViewModel _currentPageViewModel;
    private List<IPageViewModel> _pageViewModels;

    #endregion

    public ApplicationViewModel()
    {
        // Add available pages
        PageViewModels.Add(new HomeViewModel());
        PageViewModels.Add(new EmployeesListViewModel());
        PageViewModels.Add(new EmployeeDetailsViewModel());

        // Set starting page
        CurrentPageViewModel = PageViewModels[0];
    }

    #region Properties / Commands

    public ICommand ChangePageCommand
    {
        get
        {
            if (_changePageCommand == null)
            {
                _changePageCommand = new RelayCommand(
                    p => ChangeViewModel((IPageViewModel)p),
                    p => p is IPageViewModel);
            }

            return _changePageCommand;
        }
    }

    public List<IPageViewModel> PageViewModels
    {
        get
        {
            if (_pageViewModels == null)
                _pageViewModels = new List<IPageViewModel>();

            return _pageViewModels;
        }
    }

    public IPageViewModel CurrentPageViewModel
    {
        get
        {
            return _currentPageViewModel;
        }
        set
        {
            if (_currentPageViewModel != value)
            {
                _currentPageViewModel = value;
                OnPropertyChanged("CurrentPageViewModel");
            }
        }
    }

    #endregion

    #region Methods

    private void ChangeViewModel(IPageViewModel viewModel)
    {
        if (!PageViewModels.Contains(viewModel))
            PageViewModels.Add(viewModel);

        CurrentPageViewModel = PageViewModels
        .FirstOrDefault(vm => vm == viewModel);
    }

    #endregion
}

雙擊行時如何更改視圖

首先,您需要為MouseDoubleClick事件添加EventTrigger:

    <DataGrid Name="gridEmployees" ItemsSource="{Binding Employees}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDoubleClick">
                <local:CustomCommandAction Command="{Binding DoubleClickCommand}" CommandParameter="{Binding ElementName=gridEmployees, Path=SelectedItems[0]}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </DataGrid>

CustomCommandAction是一個類,它繼承自TriggerAction,並用作視圖模型中事件和命令之間的鏈接。 這是代碼:

public sealed class CustomCommandAction : TriggerAction<DependencyObject>
{
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(CustomCommandAction), null);

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
        "Command", typeof(ICommand), typeof(CustomCommandAction), null);

    public ICommand Command
    {
        get
        {
            return (ICommand)this.GetValue(CommandProperty);
        }
        set
        {
            this.SetValue(CommandProperty, value);
        }
    }

    public object CommandParameter
    {
        get
        {
            return this.GetValue(CommandParameterProperty);
        }

        set
        {
            this.SetValue(CommandParameterProperty, value);
        }
    }

    protected override void Invoke(object parameter)
    {
        if (this.AssociatedObject != null)
        {
            ICommand command = this.Command;
            if (command != null)
            {
                if (this.CommandParameter != null)
                {
                    if (command.CanExecute(this.CommandParameter))
                    {
                        command.Execute(this.CommandParameter);
                    }
                }
                else
                {
                    if (command.CanExecute(parameter))
                    {
                        command.Execute(parameter);
                    }
                }
            }
        }
    }
}

之后,最簡單的解決方案是在您的命令Execute方法中使用ChangeViewModel方法,例如:

...

_doubleClickCommand = new RelayCommand(OnDoubleClick);
...

    private RelayCommand _doubleClickCommand = null;
    private ApplicationViewModel _applicationViewModel;

    private void OnDoubleClick(object obj)
    {
        EmployeeDetailsViewModel selectedModel = obj as  EmployeeDetailsViewModel;

        _applicationViewModel.ChangeViewModel(selectedModel);
    }

    public ICommand DoubleClickCommand
    {
        get
        {
            return _doubleClickCommand;
        }
    }

如何從第一列(employee_id)獲取值並將其傳遞到EmployeeDetails視圖

對於您的DataGrid,您可以使用EmployeeDetailsViewModel的集合作為ItemsSource。 如果這樣做,所選項目將作為EmployeeDetailsViewModel的實例傳遞到命令Execute方法,您將能夠從那里獲取ID。

您似乎缺少顯示所選視圖所需的元素。 如果查看鏈接的示例,請注意ItemsControl包含在Border中 ,而Border又在DockPanel內部。

DockPanel下方有一個ContentControl ,它是顯示所選視圖所需的關鍵元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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