【发布时间】:2015-02-16 01:42:56
【问题描述】:
我已将 DependencyProperty 添加到我的视图中,绑定到 DependencyProperty 有效,但前提是我没有同时设置 DataContext。
GenericView.xaml
<UserControl x:Class="GenericProject.View.GenericView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Button Command="{Binding VMFactory.CreateViewModelCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<TextBox IsEnabled="False" Text="{Binding SomeProperty, Mode=OneWay}" />
</StackPanel>
</UserControl>
GenericView.xaml.cs
public partial class GenericView : UserControl
{
// The DependencyProperty for VMFactory.
public static readonly DependencyProperty VMFactoryProperty = DependencyProperty.Register("VMFactory", typeof(VMFactoryViewModel<GenericViewModel>), typeof(GenericView));
public VMFactoryViewModel<GenericViewModel> VMFactory
{
get { return (VMFactoryViewModel<GenericViewModel>)GetValue(VMFactoryProperty); }
set { SetValue(VMFactoryProperty, value); }
}
public GenericView()
{
InitializeComponent();
}
}
在这里,我创建了两个视图来说明手头的问题。第一个视图中的 VMFactory 绑定将失败,因为我设置了 DataContext。第二个视图会成功,这个行为的原因是什么?
MainPage.xaml
<vw:GenericView DataContext="{Binding Generic}" VMFactory="{Binding GenericFactory}" />
<vw:GenericView VMFactory="{Binding GenericFactory}" />
【问题讨论】:
-
(如果它不适用,请忽略这个粗俗的评论!)您没有创建 ViewModel 来封装您的 UserControls 的逻辑,是吗?因为没有。您不会为您的 UserControls 创建 ViewModel。 UserControls 应该只包含 UI 逻辑,并且它们应该像任何其他控件一样设计。 TextBox 有 TextBoxViewModel 吗? 否。 您遇到的 PITA 是因为您正在尝试实现反模式。停下来。这是我的答案,其中包含更多详细信息stackoverflow.com/a/25796096/1228
-
... ... 什么? UserControl 不应该有它公开的命令,它应该有一个 ICommand 类型的公共 DP,它使用它来允许其他 VM 将 它们的 命令绑定到它。您不应该有 VMFactoryUserControl 和 VMFactoryViewModel。那就是那里的代码气味。所以我不清楚你在这里做什么,我猜。
-
如果您开始遵循实际的 MVVM 模式,而不是创建一个看起来相似但实际上使事情更复杂的反模式,那么绑定将开始更好地工作。
-
我不确定我是否同意这个@Will。复合 UI 是使用视图模型和用户控件构建的。 Microsoft 的 Patterns & Practices 团队使用用户控件和视图模型为 WPF 和 Windows Store 应用程序提供 Prism 以实现模块化。您的“文本框没有视图模型”不是一个公平的论点。文本框是控件,而不是用户控件。有区别。
-
@我已经做到了。使用 prism 和用户控件构建了两个企业应用程序。它们运行良好,维护它们没有任何问题。