C# 通过MVVM模式创建UserControl-DataContext并绑定到父级
我使用MVVM模式,因此我自己的控件包含视图和视图模型。C# 通过MVVM模式创建UserControl-DataContext并绑定到父级,c#,wpf,mvvm,binding,user-controls,C#,Wpf,Mvvm,Binding,User Controls,我使用MVVM模式,因此我自己的控件包含视图和视图模型。 ViewModel通过DataContext属性与View连接。这使得绑定出现问题。为什么? 假设这种情况: 我创建了新的用户控件,例如“SuperTextBox”。它有一个属性“SuperValue”。现在我做类似的事情: <Window> <Window.DataContext> <vm:WindowViewModel/> </Window.DataContex
ViewModel通过DataContext属性与View连接。这使得绑定出现问题。为什么? 假设这种情况:
我创建了新的用户控件,例如“SuperTextBox”。它有一个属性“SuperValue”。
现在我做类似的事情:
<Window>
<Window.DataContext>
<vm:WindowViewModel/>
</Window.DataContext>
<local:SuperTextBox SuperValue="{Binding Test}"/>
</Window>
<UserControl>
<Grid>
<Grid.DataContext>
<vm:UserControlViewModel />
</Grid.DataContext>
// here realy code of control
</Grid>
</UserControl>
我认为“绑定过程”将SuperTextBox.SuperValue与Window.DataContext.Test连接起来,但没有,“绑定过程”将SuperTextBox.SuperValue与SuperTextBox.DataContext.Test连接起来,这对我来说是不自然和误导的
其他控件,如“TextBox”,我可以以上述方式使用,因为它们没有数据上下文
如何使用MVVM模式创建用户控件,保持自然绑定(到父控件的DataContext)
编辑:
我得到了很多关于如何绑定到父级的答案,但我在前面就知道了。问题是-如何通过MVVM patern(具有ViewModel)创建UserControl并保持自然绑定-默认为父级DataContext。
我想要ViewMoldel,但仍然可以这样绑定:
<local:SuperTextBox SuperValue="{Binding Test}"/>
<local:SuperTextBox SuperValue="{Binding Path=DataContext.Test, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
可能吗?您需要“查找”其窗口祖先的datacontext。您的绑定如下所示:
<local:SuperTextBox SuperValue="{Binding Test}"/>
<local:SuperTextBox SuperValue="{Binding Path=DataContext.Test, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
任何
控件上应用的所有绑定始终首先在其DataContext中查找绑定。如果未为控件设置DataContext,则除非找到DataContext,否则它将沿着可视树走到其父级
即使将文本框上的DataContext
设置为与窗口的DatContext不同的值,它也将始终在该特定的DataContext上搜索属性Test
,而不是在窗口的DataContext上搜索属性
<TextBox>
<TextBox.DataContext>
<vm:ViewModelForTextBox/>
</TextBox.DataContext>
<TextBox.Text>
<Binding Path="Test"/>
</TextBox.Text>
</TextBox>
有关更多说明,请参阅MSDN文章。您应该发布SuperTextBox代码,因为存在错误
通常,您会创建一个带有依赖属性的usercontrol(在您的例子中是“SuperValue”),现在最重要的是您不会将SuperTextBox的datacontext设置为它自己
必须在SuperTextBox中使用elementname绑定才能绑定到“SuperValue”
我觉得奇怪地回答了我的问题,但是…
在我自己的控制下,我做了这样的事情:
<Window>
<Window.DataContext>
<vm:WindowViewModel/>
</Window.DataContext>
<local:SuperTextBox SuperValue="{Binding Test}"/>
</Window>
<UserControl>
<Grid>
<Grid.DataContext>
<vm:UserControlViewModel />
</Grid.DataContext>
// here realy code of control
</Grid>
</UserControl>
//这里是真正的控制代码
现在我可以在控制之外使用“自然”绑定了。:)谢谢,但我知道。:)我需要关于通过MVVM模式创建用户控件的“模式和实践”的信息。我可以使用MVVM,并且仍然像“文本框”中一样使用正常/自然的竞价吗“控制?这没有什么不自然的。对于任何控制元素,如果它的ItemsSource中有单个项的datacontext,则必须执行相同的操作。例如,如果要将ListViewItem的可见性绑定到viewmodel中的某个值,但ListView具有ItemsSource集,则必须使用此绑定方法。感谢您的回答,但当我使用MVVM模式创建UserControl时,我必须拥有(或希望拥有)viewmodel。因此,要将ViewModel注入到视图中,我必须使用DataContext,这使得绑定不自然。我的问题是如何避免这种情况——我可以用另一种方式加入ViewModel吗(这不会破坏绑定)?当您创建一个具有依赖属性的真实usercontrol时,这是可能的,就像我发布的一样。但我将编辑我的答案以显示另一种“不自然”的方式:)