【问题标题】:How do I override the ViewModel DataContext so I can bind to objects in the View (Mvvm-Light)?如何覆盖 ViewModel DataContext 以便我可以绑定到 View (Mvvm-Light) 中的对象?
【发布时间】:2011-01-18 08:16:27
【问题描述】:

我正在使用 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 绑定到代码隐藏中的本地属性”。

我仍然不明白下面提供的两种解决方案。所以下面还有更多问题......

【问题讨论】:

    标签: c# silverlight xaml windows-phone-7 mvvm-light


    【解决方案1】:

    通常,当您使用 MVVM 时,几乎所有可绑定属性都在您的 ViewModel 上,而不是在您的 View 上。但是,显然有时您希望创建具有属性的组件控件。你能解释一下这个属性是什么以及为什么它只需要是视图上的一个属性吗?

    话虽如此...我猜你的 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}" />
    

    【讨论】:

    • 好的,当我第一次阅读您的答案时,我并没有理解它。我以为你在建议一些不同的东西,你的样本不完整。但现在我看到您提供的解决方案与我在上面找到的相同。
    • 让我追问一下:在使用 DataContext 的示例中,DataContext 的其他语法会到达根目录吗?我发誓我以前看过一些东西,但不记得了。
    • 哦,你说得对,这些东西属于我的 ViewModel。我很懒惰,然后因为想知道如何做到这一点而分心。我现在将所有代码移回它所属的 VM。
    • 在 Silverlight 中,唯一的其他内置选项是 RelativeSource={RelativeSource TemplatedParent},尽管您只能在控件模板中使用它。 Silverlight 5 应该引入基于 AncestorType 使用 RelativeSource 的能力,这允许绑定遍历 VisualTree 并找到特定类型。这就是它通常在 WPF 中完成的方式。 msdn.microsoft.com/en-us/library/ms743599.aspx
    【解决方案2】:

    如果我是正确的,您可以将 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 中使用 做同样的事情。我不知道如何为我的视图定义等效的“xmlns:crap”。
    • “Application.Views”是我的应用程序中的 Views 目录。但我相信,如果你想绑定到 xaml 中的对象,那么 joe mcBride 的解决方案会更好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多