【问题标题】:Xamarin Forms: Call Command of ViewModel from DataTemplateXamarin Forms:从 DataTemplate 调用 ViewModel 的命令
【发布时间】:2019-11-07 21:15:59
【问题描述】:

我在这里遇到了绑定问题。

我在控件模板中创建了一个可绑定布局:

<ContentView x:Name="SettingsMenu" ControlTemplate="{StaticResource HeaderTemplate}" AbsoluteLayout.LayoutBounds="0.5,0.5,1,1" 
AbsoluteLayout.LayoutFlags="All">               
    <ScrollView Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">                   
        <StackLayout x:Name="SettingsStack" BindableLayout.ItemsSource="{Binding Settings}" BindableLayout.ItemTemplateSelector="{StaticResource SettingsSelectorTemplate}" Orientation="Vertical" Spacing="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />           
    </ScrollView>        
</ContentView>

我想做的是在视图模型中调用一个命令。该调用位于项目模板选择器中,作为 App.xml 中的资源字典

<ResourceDictionary>
    <DataTemplate x:Key="PlaceholderSettingsTemplate">
        ### SOME STUFF
     </DataTemplate>
     <DataTemplate x:Key="HeaderSettingsTemplate">
             ### SOME STUFF
         <Grid ...>
             <Grid.GestureRecognizers>
                 <TapGestureRecognizer Tapped="ButtonClick" Command="{Binding BindingContext.SettingsTap, Source={x:Reference SettingsPage}}" CommandParameter="{Binding}" />  ########## <--------- WHAT TO USE FOR SOURCE?
             </Grid.GestureRecognizers>
         </Grid>
     </DataTemplate>
     <data:SettingsSelector x:Key="SettingsSelectorTemplate" Placeholder="{StaticResource PlaceholderSettingsTemplate}" Heading="{StaticResource HeaderSettingsTemplate}" Content="{StaticResource ContentSettingsTemplate}" />
</ResourceDictionary>

在将它移到 App.xml 文件的资源字典中之前,我只是使用了父 Contentview 的 x:Name。但是:我不能再按名称引用它,因为我将它移到了 App.xml 中的资源字典中。

现在,答案可能很简单,但我就是找不到解决方案。

感谢任何帮助。

亲切的问候

【问题讨论】:

    标签: xamarin xamarin.forms binding datatemplate


    【解决方案1】:

    您可以使用包含所有内容的数据模板的 Grid 找到 SettingsStack StackLayout。由于SettingsStack 与父内容视图具有相同的绑定上下文,因此您可以在 App.cs 中访问绑定上下文,如下所示:

    <DataTemplate x:Key="HeaderSettingsTemplate">
        <!--### SOME STUFF-->
        <Grid x:Name="ParentGrid">
            <Grid.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding Parent.BindingContext.SettingsTap, Source={x:Reference ParentGrid}}" CommandParameter="{Binding}" />
            </Grid.GestureRecognizers>
        </Grid>
    </DataTemplate>
    

    ParentGrid 的父级是您当前页面上的 SettingsStack

    【讨论】:

      【解决方案2】:

      从项目模板(即使它位于不同的文件中),您可以使用以下命令访问其祖先的视图模型:

      Command="{Binding Source={RelativeSource AncestorType={x:Type SettingsViewModel}}, Path=SettingsTap}" CommandParameter="{Binding}"
      

      在这种情况下,我只是假设祖先的视图模型的名称是 SettingsViewModel,但你明白了。

      这是一篇关于相对绑定的有趣文章,它还描述了其他场景:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/relative-bindings#bind-to-an-ancestor

      干杯。

      【讨论】:

      • 在我的情况下,直系父母无法工作。你的回答让我走上了正确的道路。非常感谢!
      【解决方案3】:

      另外一种方式,我们可以直接将ContentPage 用作AncestorType。然后用BindingContext绑定命令。

      {Binding BindingContext.SomeCommand, Source={RelativeSource AncestorType={x:Type ContentPage}}}
      

      完整示例

      <DragGestureRecognizer
          DragStartingCommand="{Binding BindingContext.SomeCommand, Source={RelativeSource AncestorType={x:Type ContentPage}}}"
          DragStartingCommandParameter="{Binding}"/>
      

      这种方式也适用于单独的资源文件(例如。MySeparateResource.xml -> MyPageView.xaml)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-12
        • 1970-01-01
        • 1970-01-01
        • 2017-06-15
        • 2023-03-27
        • 2020-02-12
        • 2021-10-25
        相关资源
        最近更新 更多