WPF с использованием ViewModelLocator в DLL wpf - PullRequest
0 голосов
/ 17 октября 2019

У меня есть проект библиотеки WPF, где у меня есть коллекция представлений и моделей представлений. В этом проекте я хочу реализовать ViewModelLocator ( VML ). Тем не менее, просматривая некоторые онлайн-ресурсы, может показаться, что мне нужен App.xaml и объявить мой Locator здесь.

<Application.Resources>
        <ResourceDictionary>
            <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
        </ResourceDictionary>        
 </Application.Resources>

Тогда в моих представлениях (xaml) мне нужно назначить контекст данных

<UserControl.DataContext>
        <Binding Path="FooViewModel" Source="{StaticResource Locator}"/>
</UserControl.DataContext>

Это имеет смысл для меня, если я работаю в приложении Windows WPF. Но как мне реализовать VML в моем проекте DLL? Я попытался создать файл App.xaml в моем dll-проекте и вставил ссылку на VML следующим образом:

<Application.Resources>
        <ResourceDictionary>
            <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
        </ResourceDictionary>        
</Application.Resources>

Но когда я пытаюсь сослаться на мой Locator в моем файле FooViewModel.xaml, я получаю

System.Windows.Markup.XamlParseException
Exception: Cannot find resource named 'Locator'. Resource names are case sensitive.

Возможно ли иметь VML в проекте dll? Если так, что я пропускаю? Большое спасибо заранее!

1 Ответ

0 голосов
/ 17 октября 2019

Вместо использования ресурса ViewModelLocator вы можете создать вложенное свойство для установки DataContext представлений в вашей управляющей библиотеке:

namespace ControlsAndResources
{
    public class View
    {
        private static readonly ViewModelLocator s_viewModelLocator = new ViewModelLocator();

        public static readonly DependencyProperty ViewModelProperty = DependencyProperty.RegisterAttached("ViewModel", typeof(string), 
            typeof(ViewModelLocator), new PropertyMetadata(new PropertyChangedCallback(OnChanged)));

        public static void SetViewModel(UserControl view, string value) => view.SetValue(ViewModelProperty, value);

        public static string GetViewModel(UserControl view) => (string)view.GetValue(ViewModelProperty);

        private static void OnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UserControl view = (UserControl)d;
            string viewModel = e.NewValue as string;
            switch (viewModel)
            {
                case "MainViewModel":
                    view.DataContext = s_viewModelLocator.MainViewModel;
                    break;
                case "FooViewModel":
                    view.DataContext = s_viewModelLocator.FooViewModel;
                    break;
                default:
                    view.DataContext = null;
                    break;
            }
        }
    }
}

Использование:

<UserControl xmlns:local="clr-namespace:ControlsAndResources" ... 
             local:View.ViewModel="MainViewModel">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...