如何覆盖ViewModel DataContext以便在View中绑定对象(Mvvm-Light)?

3
我是使用Mvvm-Light框架的,一直以来都忽略了XAML中绑定的真正工作方式。以下是我的XAML代码:

<phone:PhoneApplicationPage.Resources>
</phone:PhoneApplicationPage.Resources>

<Grid x:Name="LayoutRoot" Background="Transparent">

    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,14">
        <TextBlock x:Name="ApplicationTitle" Text="{Binding SecuritySystemName}" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock x:Name="PageTitle" Text="{Binding PageName}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <TextBlock Name="textCode" 
        DataContext="{WHAT GOES HERE to bind to properties on my View (SecurityPanelPage class)}"    
        Text="{Binding Path=Code}" />

</Grid>

{Binding SecuritySystemName} 和 {Binding PageName} 正确绑定到我的ViewModel(SecuirtyPanelViewModel)。但我希望TextBlock元素中的{Binding Code}绑定到我的VIEW(而不是ViewModel)。

我已经搜索了很多文档和示例,解释了DataContext和Binding支持的语法和值。但没有什么有用的信息。

我想知道的是如何设置DataContext(或在{Binding ...}中指定某些内容),以便将其指向我的View对象。我尝试过“Self”和各种“RelativeSource”方法,但都没有成功。猜测并不是有效的方法,因为在XAML被解析之前进入调试器需要太长时间。

谢谢。

更新 - 我找到了一个答案,让我可以继续前进,但我仍然不理解,所以我有跟进问题要问下面的优秀发帖者...

以下是有效的内容:

<phone:PhoneApplicationPage x:Name="ThisPage">
   <TextBlock Name="textCode" Text="{Binding Code, ElementName=ThisPage"/>
</phone:PhoneApplicationPage>

我在这里找到了一个提示:http://bursjootech.blogspot.com/2007/12/bind-from-xaml-to-local-property-in.html 他的问题不同:如何“从XAML绑定到后台代码中的本地属性”。
我仍然不理解下面提供的两个解决方案。因此还有更多问题...
2个回答

5
通常情况下,当您使用MVVM时,几乎所有可绑定属性都在ViewModel上而不是Views上。但是,显然有时您需要创建具有属性的组件控件。您能解释一下什么是属性以及为什么它需要成为仅限于视图的属性吗?
话虽如此...我猜您的SecurityPanelPage是用于显示XAML的视图?
您可以为控件命名,然后使用ElementName绑定。这样,您就不需要设置DataContext。
<phone:PhoneApplicationPage
  x:Name="controlName"
  x:Class="SomeNamespace.SecurityPanelPage">
</phone:PhoneApplicationPage>

然后您的绑定更改为:

<TextBlock
  Name="textCode" 
  Text="{Binding Path=Code, ElementName=controlName}" />

为了明确设置DataContext,您可以执行以下操作:
<TextBlock
  Name="textCode" 
  DataContext="{Binding ElementName=controlName}"
  Text="{Binding Path=Code}" />

好的,当我第一次阅读到你的回答时,我不理解它。我认为你在提出不同的建议,而你的示例并不完整。但现在我明白了,你提供的是与我之前发现的相同的解决方案。 - tig
让我问一个跟进问题:在使用DataContext的示例中,还有哪些DataContext的语法可以到达根目录?我发誓之前看到过一些东西,但现在想不起来了。 - tig
哦,你说得对,这些东西应该放在我的 ViewModel 中。我当时有点懒,然后又被想知道如何做这件事的想法分散了注意力。现在我正在把所有代码移回到它应该在的 VM 中。 - tig
在Silverlight中,另一个内置选项是RelativeSource={RelativeSource TemplatedParent},但只能在控件模板中使用。Silverlight 5应该引入基于AncestorType的RelativeSource使用能力,它允许绑定沿着VisualTree向上查找特定类型。这通常是在WPF中完成的方式。http://msdn.microsoft.com/en-us/library/ms743599.aspx - Joe McBride

1
如果我没记错的话,你可以在app.xaml中添加资源到你想要的视图。

A.E:

xmlns:crap="clr-namespace:Application.Views"
<Application.Resources>
    <ResourceDictionary>
        <crap:MyViewPage x:Key="MyViewPage" />
    </ResourceDictionary>  
</Application.Resources>

然后像这样使用它:"{Binding MyProperty, source={StaticResource MyViewPage}"。

希望这能起作用/有所帮助。


我该如何在我的视图的XAML中使用phone:ApplicationPage.Resources来完成同样的事情。我无法弄清楚如何为我的视图定义等效的“xmlns:crap”。 - tig
"Application.Views"是我的应用程序中的视图目录。 但我认为,如果您想要在XAML中绑定对象,那么Joe McBride的解决方案更好。 - Theun Arbeider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接