在 .NET MAUI 中的 ContentPresenter 中绑定上下文

问题描述 投票:0回答:1

我还是 .NET MAUI 的新手,所以我在基本概念和最佳实践方面仍然存在一些问题。目前我有点挣扎于

ContentPresenter

所以我有一个自定义组件 (

ContentView
),其中
ControlTemplate
使用
ContentPresenter
。让我们命名为
CustomControl.xaml

<ContentView>
    <ContentView.ControlTemplate>
        <ControlTemplate>
            <ContentPresenter />
        </ControlTemplate>
    </ContentView.ControlTemplate>
</ContentView>

显然我正在使用 MVVM,所以当我想在视图中使用

CustomControl
时,我会这样做:

<ContentPage>
    <local:CustomControl>
        <Button Text="Click me" Command="{Binding DoSomethingCommand}" />
    </local:CustomControl>
</ContentPage>

其中

DoSomethingCommand
在我的视图模型中定义。

这效果非常好,太棒了!但是,如果我想在我的

ContentPresenter
中使用多个
CustomControl
该怎么办?据我所知,我应该像这样绑定
ContentPresenter
的内容:

<ContentView>
    <ContentView.ControlTemplate>
        <ControlTemplate>
            <ContentPresenter Content="{TemplateBinding MyContent}" />
        </ControlTemplate>
    </ContentView.ControlTemplate>
</ContentView>

当然,我已经在代码隐藏文件中定义了

BindableProperty
。现在我像这样使用我的
CustomControl

<ContentPage>
    <local:CustomControl>
        <local:CustomControl.MyContent>
            <Button Text="Click me" Command="{Binding DoSomethingCommand}" />
        </local:CustomControl.MyContent>
    </local:CustomControl>
</ContentPage>

我的按钮准确地显示在它应该的位置,但是......点击它时绝对没有效果:(

我搜索了一个解决方案,我发现我可以这样使用它:

<Button Text="Click me" Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:MyViewModel}}, Path=DoSomethingCommand}" />

这确实有效,但它看起来很糟糕,我根本不明白:(有人可以帮助我理解为什么这个简单的绑定到我的命令不起作用吗?也许我可以/应该以某种方式修改我的

CustomControl

xamarin maui
1个回答
0
投票

可以看到在父元素

MyContent
中创建了子元素
CustomCrntrol
。使用bacis绑定无法从子元素获取数据。因为您将视图模型绑定到父元素而不是子元素。

 <local:CustomControl>
        <local:CustomControl.MyContent>
            <Button Text="Click me" Command="{Binding DoSomethingCommand}" />
        </local:CustomControl.MyContent>
</local:CustomControl>

这就是为什么你需要在按钮中使用相对绑定。 FindAncestor 指示绑定元素的可视树中的祖先。此模式应该绑定到由 AncestorType 属性代表的祖先控件。

<Button Text="Click me" Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:MyViewModel}}, Path=DoSomethingCommand}" />
© www.soinside.com 2019 - 2024. All rights reserved.