如何在用户控件中绑定命令?

时间:2019-05-16 19:57:57

标签: wpf mvvm data-binding ioc-container structuremap

简介

我正在尝试使用Structuremap IoC容器将C#WPF应用程序覆盖到MVVM模式中,以进行依赖项注入。

在尝试在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%相同: Part 1 Part 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传递给父级ViewModel。

1 个答案:

答案 0 :(得分:0)

谢谢mm8,我解决了以下问题:

MainWindowViewModel:

name

现在我可以将UserControl的ViewModel绑定到UserControlView中:

// Get response
var jsonData = pm.response.json();
var resultCount = jsonData.length;

// Test arrays
var hasPregnancy = [];
var doesntHavePregnancy = [];

// Loop through and set arrays with matching data
for (i = 0; i < resultCount; i++) {
  var id = jsonData[i].id;
  var modelString = jsonData[i].name.toLowerCase();
  if (modelString.includes("pregnancy")) {
    hasPregnancy.push({
      "id": id,
      "hasPregnancy": modelString.has("pregnancy")
    });
  } else {
    doesntHavePregnancy.push({
      "id": id
    });
  }
}

// Check that each object in response contained keyword and length matches from test
pm.test("Expect response to contain pregnancy in each object", function() {
  console.log(hasPregnancy);
  console.log(doesntHavePregnancy);
  pm.expect(hasPregnancy.length).to.equal(resultCount);
});

这不完全是我想要的,但它使我免于灾难性的意大利面条式代码。我认为我有一个子视图集合是可行的,如果它在父视图中不可用,该子视图集合可用于自动绑定来自他们的命令。但这现在足以进行项目。谢谢!