C# 通过MVVM模式创建UserControl-DataContext并绑定到父级

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

我使用MVVM模式,因此我自己的控件包含视图和视图模型。
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时,这是可能的,就像我发布的一样。但我将编辑我的答案以显示另一种“不自然”的方式:)