MVVM从TabControl绑定到Page.DataContext

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MVVM从TabControl绑定到Page.DataContext相关的知识,希望对你有一定的参考价值。

我正在使用MVVM Light构建我的WPF应用程序,并使用IOC创建ViewModel。

该页面初始化其DataContext,如下所示:

DataContext="{Binding Main, Source={StaticResource Locator}}"

TabControl的内容绑定到另一个ViewModel,因此默认情况下TabControl中的绑定将访问选项卡ViewModel。

现在,我如何在XAML中访问页面ViewModel?

在切换到使用IOC之前,ViewModel是作为StaticResource创建的,我可以像这样访问它

Zoom="{Binding Zoom, Source={StaticResource ViewModel}, Mode=TwoWay}"

然后我也可以通过Locator访问它,但是我不喜欢这种语法,如果使用密钥创建了这个ViewModel实例会发生什么?我不认为内容绑定应该关心这些细节。

Zoom="{Binding Main.Zoom, Source={StaticResource Locator}, Mode=TwoWay}"

这样做的正确方法是什么?

答案

您可以将RelativeSource Binding与Mode设置为FindAncestor。这将允许您绑定到窗口的DataContext(或包含您的选项卡控件的任何其他元素),而无需了解它。

我根据您的描述设置了一个简单的示例。我有2个简单的View模型:

public class MainViewModel : ViewModelBase
{
    public double Zoom { get; } = 1;
}

public class TabViewModel : ViewModelBase
{
    public double Zoom { get; } = 2;
}

这是我的xaml的内容:

<Window
...blah blah blah...
DataContext="{Binding Main, Source={StaticResource Locator}}"
>
<Grid>
    <TabControl>
        <TabItem DataContext="{Binding Tab, Source={StaticResource Locator}}" Header="TabItem">
            <StackPanel>
                <Label Content="{Binding DataContext.Zoom, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" />
                <Label Content="{Binding Zoom}" />
            </StackPanel>
        </TabItem>
    </TabControl>
</Grid>

第一个标签从MainViewModel获取它的值,第二个标签从TabViewModel获取。

我发现的一个缺点是这种绑定的设计时间数据不能正常工作。这可以通过提供回退值来解决。

希望这能解决你的问题。

以上是关于MVVM从TabControl绑定到Page.DataContext的主要内容,如果未能解决你的问题,请参考以下文章

如何将 TabControl 绑定到 ViewModel 集合?

使用 TabControl (MVVM) 显示不同的 ViewModel

WPF Adorner 在TabControl切换TabItem时消失

WPF MVVM从入门到精通3:数据绑定

如何将 TabControl 的项目绑定到 wpf 中的可观察集合?

WPF MVVM从入门到精通5:PasswordBox的绑定