Невозможно зарегистрировать View в ViewModel вручную с помощью Prism.Mvvm.ViewModelLocationProvider - PullRequest
2 голосов
/ 04 августа 2020

Структура папки -

Project Named 'Home'
|> Views > HomeView.xaml
|> ViewModels > HomeViewModel.cs
|> HomeModule.cs (an IModule class)

HomeView.XAML (Примечание: AutoWireViewModel имеет значение FALSE)

<UserControl
    x:Class="Tally.Sync.Home.Views.HomeView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:Tally.Sync.Home.Views"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:prism="http://prismlibrary.com/"
    d:DesignHeight="450"
    d:DesignWidth="800"
    prism:ViewModelLocator.AutoWireViewModel="False"
    mc:Ignorable="d">
    <Grid>
        <TextBlock
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            FontSize="28"
            Text="{Binding Message}" />
    </Grid>
</UserControl>

HomeViewModel.cs

public class HomeViewModel : BindableBase
{
    private string _message = "Hi There!";
    public string Message
    {
        get { return _message; }
        set { SetProperty(ref _message, value); }
    }

    public HomeViewModel()
    {

    }
}

HomeModule.cs

public class HomeModule : IModule
{
    private readonly IRegionManager _regionManager;

    public HomeModule(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }

    public void OnInitialized(IContainerProvider containerProvider)
    {
        _regionManager.RegisterViewWithRegion("ContentRegion", typeof(HomeView));
    }

    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        ViewModelLocationProvider.Register<HomeView, HomeViewModel>();
    }
}

Как видите, я регистрирую HomeView и HomeViewModel с помощью ViewModelLocationProvider . Но это не работает. Мой код работает должным образом, когда AutoWireViewModel установлен на True

Что я делаю не так? Я знаю, что могу подключить его автоматически, но я пытаюсь изучить Prism и в одном из видеороликов Брайана Лагунаса упоминается, что подключение вручную выполняется быстрее, так как отражение не требуется.

1 Ответ

2 голосов
/ 04 августа 2020

Когда вы регистрируете виды и просматриваете модели вручную в локаторе модели вида, вам все равно нужно включить автоматическое подключение в модели вида, это просто изменит то, как ViewModelLocator разрешает вид и его просмотреть модель. Установка False отключит его, поэтому ничего не решит.

prism:ViewModelLocator.AutoWireViewModel="True"

Как видно из справки источник для ViewModelLocationProvider, зарегистрированные представления будут проверяться в первую очередь, когда разрешение модели представления. Если регистраций нет, будет использован откат к разрешению с соглашением об именах через отражение.

public static void AutoWireViewModelChanged(object view, Action<object, object> setDataContextCallback)
{
   object viewModel = GetViewModelForView(view);

   if (viewModel == null)
   {
      // Try to resolve the view model via regsitrations
      var viewModelType = GetViewModelTypeForView(view.GetType());

      // If views and view models are not registerd, fallback to reflection
      if (viewModelType == null)
         viewModelType = _defaultViewTypeToViewModelTypeResolver(view.GetType());

      //...
   }

   // ...
}

Поскольку ViewModelLocator разрешит представление как через регистрацию, так и через резервное соглашение об именах, вы не сделали заметьте разницу. Если вы переименуете свой HomeViewModel в HomeFooBar или что-нибудь еще, что не соответствует соглашению об именах, откат не удастся, и вы увидите, что он работает, как описано выше.

[... ] проводка вручную выполняется быстрее, так как отражение не требуется.

Я думаю, что есть много недоразумений относительно отражения. В этом случае с несколькими видами вы даже не заметите никакой разницы, и это намного удобнее. Не оптимизируйте преждевременно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...