Как я могу связать команду в пользовательском элементе управления? - PullRequest
0 голосов
/ 16 мая 2019

Введение

Я пытаюсь покрыть свое приложение C # WPF в шаблоне MVVM, используя контейнер IoC Structuremap для внедрения зависимостей.

Мой код работает хорошо, пока я не попытаюсь использовать ту же привязку команд в UserControls, что и в Windows.

Я попробовал следующее

Если я пытаюсь связать команду в определенном UserControl, я получаю следующую ошибку: System.Windows.Data Error: 40 : BindingExpression path error: 'HelloWorldCommand' property not found on 'object' ''MainWindowViewModel' (HashCode=7304143)'. BindingExpression:Path=HelloWorldCommand; DataItem='MainWindowViewModel' (HashCode=7304143); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand')

Итак, проблема в том, что мой HelloWorldCommand в моем CustomUserControlViewModel, который содержит и связывает MainWindowViewModel.

Мой фрагмент кода

Мой код на 90% такой же, как в следующем уроке: Часть 1 часть 2

Отличается только метод ObjectFactory, который можно увидеть ниже:

public sealed class ObjectFactory
    {
        public static IContainer Container { get; private set; }

        private static Action<ConfigurationExpression> _initialiseMethod;
        private static readonly Lazy<IContainer> _containerBuilder =
            new Lazy<IContainer>(CreateContainer, LazyThreadSafetyMode.ExecutionAndPublication);

        public static void Initialise()
        {
            Container = _containerBuilder.Value;
        }

        private static IContainer CreateContainer()
        {
            return new Container(config =>
            {
                #region services
                config.For<IFileDisplayerService>().Singleton().Use<FileDisplayerService>();
                config.For<IWatermarkService>().Singleton().Use<WatermarkService>();
                #endregion

                #region windows
                config.For<IWindow>().Use<MainWindow>();
                config.For<IWatermarkWindow>().Use<WatermarkSettingsWindow>();

                config.For<IMainWindow>().Singleton().Use<MainWindow>();
                config.For<IMainWindowViewModel>().Singleton().Use<MainWindowViewModel>();

                config.For<IWatermarkSettingsWindow>().Singleton().Use<WatermarkSettingsWindow>();
                config.For<IWatermarkSettingsWindowViewModel>().Singleton().Use<WatermarkSettingsWindowViewModel>();
                #endregion

                #region views
                config.For<IFileListView>().Use<FileListView>();
                config.For<IFileListViewModel>().Use<FileListViewModel>()
                    .Ctor<IView>().Is<FileListView>();

                config.For<IFileDisplayerView>().Use<FileDisplayerView>();
                config.For<IFileDisplayerViewModel>().Use<FileDisplayerViewModel>()
                    .Ctor<IView>().Is<FileDisplayerView>();
                #endregion
            });
        }
    }

Мой вопрос

Мой конкретный вопрос заключается в том, как я могу связать команду с пользовательским элементом управления, который имеет собственную и родительскую ViewModel? Это не показано в примере выше.

Я думаю, что родительский ViewModel должен также содержать команду, но я не знаю, как передать ее родительскому ViewModel из дочернего ViewModel.

1 Ответ

0 голосов
/ 17 мая 2019

Спасибо, мм8. Я решил свою проблему, как в следующем режиме:

MainWindowViewModel:

public IViewModel FileListViewModel { get; set; }
public IViewModel FileDisplayerViewModel { get; set; }

public IView FileListView { get; set; }
public IView FileDisplayerView { get; set; }

public MainWindowViewModel(IWindow window, IContainer container,
        IFileDisplayerViewModel fileDisplayerViewModel, IFileListViewModel fileListViewModel) : base(window, container)
        {
            FileListViewModel = fileListViewModel;
            FileListView = FileListViewModel.View;

            FileDisplayerViewModel = fileDisplayerViewModel;
            FileDisplayerView = FileDisplayerViewModel.View;
        }

Теперь я могу привязать ViewModel моего UserControl к UserControlView:

<Button Command="{Binding FileListViewModel.HelloWorldCommand}" Width="100" Height="20" Content="Push" Background="White"></Button>

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

...