首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在创建后检索控件的视图模型?

如何在创建后检索控件的视图模型?
EN

Stack Overflow用户
提问于 2013-01-09 23:08:24
回答 2查看 119关注 0票数 1

我有一个窗口和一个UserControl。UserControl创建自己的视图模型,如下所示:

代码语言:javascript
运行
复制
<UserControl x:Class="UiInteraction.UserControl3"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:UiInteraction"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">

    <UserControl.DataContext>
        <local:UserControl3Vm/>
    </UserControl.DataContext>

    <StackPanel>
        <TextBlock Text="{Binding String1}"/>
    </StackPanel>

</UserControl>

当窗口实例化UserControl时,我希望窗口的视图模型能够检索UserControl的视图模型。

代码语言:javascript
运行
复制
<Window x:Class="UiInteraction.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:UiInteraction"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:MainWindowVm/>
    </Window.DataContext>

    <StackPanel>
        <local:UserControl3 DataContext="{Binding UserControl3Vm, Mode=OneWayToSource}"/>
    </StackPanel>

</Window>

窗口的视图模型有一个类型为object的可公开设置的属性。对于DataContext绑定,我期望一旦创建了UserControl3,它的DataContext (它是对其视图模型的引用)的值将被分配给窗口的视图模型上的UserControl3Vm属性。

实际发生的情况是,使用空值调用Window.UserControl3Vm属性设置器。

为什么会发生这种情况,实现我心目中的目标的最佳方法是什么?

我知道,将UserControl的视图模型实例化为窗口的视图模型上的属性,并让UserControl简单地绑定到该属性上会更容易(这也会最小化视图与视图模型之间的耦合)。但在我工作的地方,他们有点疯狂,他们更喜欢先查看MVVM,而不是先查看模型,所以我在寻找最解耦的方法来使视图模型在视图模型创建时有效地结合在一起。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-09 23:18:51

我不认为在没有代码隐藏的情况下使用OneWayToSource绑定是行不通的。

最初,您的UserControl.DataContext被设置为UserControl3vm的一个实例,但是您用绑定替换了UserControl3vm,因此您的原始UserControl3vm不再在任何地方被引用。

要使OneWayToSource绑定工作,必须首先将DataContext设置为OneWayToSource绑定,然后从UserControl内部将绑定的源设置为UserControl3vm的新实例。

如果我没记错的话,您可以使用BindingOperations.GetBindingExpression获取绑定,并更新它的DataItem属性。您不能简单地设置UserControl.DataContext,因为它会覆盖您的OneWayToSource绑定。

就我个人而言,我只会在代码隐藏的Loaded事件中这样做

如果他们坚持使用View-First MVVM,那么View正在控制应用程序流,我看不出有任何理由让应用程序逻辑远离View的代码隐藏。

因此,只需在已加载的事件中将Window.DataContext.UserControl3Vm属性设置为UserControl3.DataContext :)

代码语言:javascript
运行
复制
<Window x:Name="MyWindow"
        Loaded="MyWindow_Loaded" 
        ... >
    <StackPanel>
        <local:UserControl3 x:Name="MyUserControl" />
    </StackPanel>
</Window>

void MyWindow_Loaded(object sender, EventArgs e)
{
    ((MainWindowVm)MyWindow.DataContext).UserControl3Vm 
        = MyUserControl.DataContext;
}
票数 2
EN

Stack Overflow用户

发布于 2013-01-10 11:31:33

这在XAML中是可能的,使用一些变通方法(对宿主元素的DataContext的访问进行黑客攻击)。该方法在here中提到。它使用Freezables

XAML是

代码语言:javascript
运行
复制
<Window x:Class="VM2VMBindingInXaml.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vw="clr-namespace:VM2VMBindingInXaml.View"
        xmlns:vm="clr-namespace:VM2VMBindingInXaml.ViewModel"
        Title="MainWindow" Height="350" Width="525" >
    <Window.Resources>
             <vm:UserControl1ViewModel x:Key="childVM"></vm:UserControl1ViewModel>
        <vm:DataResource x:Key="childVmBinding" BindingTarget="{Binding ElementName=child, Path=DataContext}"/>
    </Window.Resources>
    <Window.DataContext>
        <vm:MainWindowViewModel x:Name="mainViewModel" >
            <vm:MainWindowViewModel.ChildViewModel>
                <vm:DataResourceBinding DataResource="{StaticResource childVmBinding}">

                </vm:DataResourceBinding>
            </vm:MainWindowViewModel.ChildViewModel>
        </vm:MainWindowViewModel>
    </Window.DataContext>
    <Grid>
        <vw:UserControl1 x:Name="child" DataContext="{Binding Source={StaticResource ResourceKey=childVM}}">
        </vw:UserControl1>
    </Grid>
</Window>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14238259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档