如何在用户控件中绑定命令?
How can I bind a command in a user control?
简介
我正在尝试使用用于依赖项注入的 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。
谢谢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>
这不完全是我想要的,但它使我免于灾难性的意大利面条代码。我认为我有一个子视图集合是可行的,如果它在父视图中不可用,它用于自动绑定来自它们的命令。但这现在足以继续该项目。谢谢!
简介
我正在尝试使用用于依赖项注入的 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。
谢谢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>
这不完全是我想要的,但它使我免于灾难性的意大利面条代码。我认为我有一个子视图集合是可行的,如果它在父视图中不可用,它用于自动绑定来自它们的命令。但这现在足以继续该项目。谢谢!