Wpf 如何在用户控件中绑定命令? 导言
我试图使用Structuremap IoC容器将我的C#WPF应用程序覆盖到MVVM模式中,以进行依赖注入 我的代码运行良好,直到我尝试在UserControls中使用与Windows相同的命令绑定 我尝试了以下方法 如果尝试在某个UserControl中绑定命令,则会出现以下错误:Wpf 如何在用户控件中绑定命令? 导言,wpf,mvvm,data-binding,ioc-container,structuremap,Wpf,Mvvm,Data Binding,Ioc Container,Structuremap,我试图使用Structuremap IoC容器将我的C#WPF应用程序覆盖到MVVM模式中,以进行依赖注入 我的代码运行良好,直到我尝试在UserControls中使用与Windows相同的命令绑定 我尝试了以下方法 如果尝试在某个UserControl中绑定命令,则会出现以下错误:System.Windows.Data错误:40:BindingExpression路径错误:“在“对象”“MainWindowViewModel”(HashCode=7304143)上找不到HelloWorldCo
System.Windows.Data错误:40:BindingExpression路径错误:“在“对象”“MainWindowViewModel”(HashCode=7304143)上找不到HelloWorldCommand”属性。BindingExpression:Path=HelloWorldCommand;DataItem='MainWindowViewModel'(HashCode=7304143);目标元素是“按钮”(名称=“”);目标属性为“Command”(类型为“ICommand”)
所以问题是我的HelloWorldCommand
是否在我的CustomUserControlViewModel
中,它包含并绑定在MainWindowViewModel
中
我的自定义代码片段
我的代码与以下教程90%相同:
只有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
});
}
}
公共密封类ObjectFactory
{
公共静态IContainer容器{get;private set;}
私有静态作用法;
私有静态只读惰性容器生成器=
新的Lazy(CreateContainer,LazyThreadSafetyMode.ExecutionAndPublication);
公共静态无效初始化()
{
Container=\u containerBuilder.Value;
}
专用静态IContainer CreateContainer()
{
返回新容器(配置=>
{
#区域服务
config.For().Singleton().Use();
config.For().Singleton().Use();
#端区
#区域窗口
config.For().Use();
config.For().Use();
config.For().Singleton().Use();
config.For().Singleton().Use();
config.For().Singleton().Use();
config.For().Singleton().Use();
#端区
#区域视图
config.For().Use();
config.For().Use()
.Ctor().Is();
config.For().Use();
config.For().Use()
.Ctor().Is();
#端区
});
}
}
我的问题
我的具体问题是,如何将命令绑定到具有自己的和父视图模型的用户控件?这在上面的示例中没有显示
我认为父视图模型也应该包含该命令,但我不知道如何将它从子视图模型传递到父视图模型。谢谢mm8我像以下模式一样解决了我的问题: 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;
}
现在,我可以将UserControl的ViewModel绑定到UserControlView中:
<Button Command="{Binding FileListViewModel.HelloWorldCommand}" Width="100" Height="20" Content="Push" Background="White"></Button>
这并不完全是我想要的,但它使我免于灾难性的意大利面代码。我认为我有一个子视图集合是可行的,如果在父视图中不可用,该集合用于自动绑定来自它们的命令。但现在这已经足够继续这个项目了。谢谢大家! “我的代码与下面的教程90%相同”表示您的代码不同。请在您的问题中分享代码的相关部分。“我认为父视图模型也应该包含该命令,但我不知道如何将它从子视图模型传递给父视图模型”--我怀疑这是个好主意,但父视图模型可以,如果它愿意,从它自己的子视图中获取它想要的任何属性--除非你用拜占庭式的IOC东西来隐藏它自己的子视图模型,在这种情况下,您已经了解了不使用这些的新原因。向我们展示。错误表明您在
MainWindowViewModel
上没有名为HelloWorldCommand
的属性。鉴于UserControl
的DataContext
似乎指向MainWindowViewModel
属性应该只在那里定义。@Bijington明白了。“…MainWindowViewModel属性应仅在此处定义。”。因此,目标是正确地将各个部分相互分离。这意味着我想在UserControl的ViewModel中实现UserControl的按钮,而不是在父窗口的ViewModel中。我的下一个想法是以编程方式将孩子的数据上下文与父母的数据上下文合并。可行吗?明天我将把我的全部代码上传到一个说明性的git repo,但不幸的是,现在我只有这些了。CustomUserControlViewModel
是MainWindowViewModel
的一个属性吗?然后可以绑定到如下属性:{Binding CustomUserControlViewModel.HelloWorldCommand}
。但是您应该发布类的定义,并澄清命令的DataContect是什么。