在Xamarin Forms中如何将ListView按钮的绑定上下文设置为其父级的绑定上下文

6
基本上,我有一个ListView,其中包含一个DataTemplate Selector,它根据ListView项目使用特定的DataTemplate。
现在,在DataTemplate中 - 我有一个带有命令的按钮,应该绑定到父ViewModel(或ListView)本身。
请注意,我只想将按钮的Command属性绑定为Text和其他属性需要绑定到按钮的当前绑定上下文。
DataTemplate的BindingContext是ListView Item bindingContext(在此示例中为Message Model),但我想能够仅将数据模板中的特定按钮绑定到父listView的viewmodel。
我该怎么做?
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage 
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
        x:Class="MobileMobile.Views.MobileMessageListView"
        Title="Message List"
        NavigationPage.BarBackgroundColor="#FF9100"
        NavigationPage.BarTextColor="White"
        xmlns:ViewSwitchers="clr-namespace:MobileMobile.ViewSwitchers;assembly=MobileMobile"
        xmlns:ViewCells="clr-namespace:MobileMobile.ViewCells;assembly=MobileMobile"
        xmlns:Extensions="clr-namespace:MobileMobile.Extensions;assembly=MobileMobile"
        >

    <ContentPage.Resources>
        <ResourceDictionary>
            <DataTemplate x:Key="botMessageDataTemplate">
                <ViewCell>
                    <Button Text="Hello!" Command="{Binding TestCommand, Source=???}" CommandParameter="Hello"/>
                </ViewCell>
            </DataTemplate>

            <ViewSwitchers:MobileMessageTemplateSwitcher x:Key="MobileMessageTemplateSwitcher" BotMessageDataTemplate="{StaticResource botMessageDataTemplate}" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <ContentPage.Content>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>

            <StackLayout Grid.Row="0" Orientation="Vertical" x:Name="MainViewStack">
                <ListView
                        CachingStrategy="RecycleElement"
                        BackgroundColor="Transparent"
                        ItemTemplate="{StaticResource MobileMessageTemplateSwitcher}"
                        IsPullToRefreshEnabled="true"
                        RefreshCommand="{Binding RefreshCommand}"
                        ItemsSource="{Binding Messages}"
                        HasUnevenRows="true"
                        IsRefreshing="{Binding IsLoading, Mode=OneWay}"
                        SeparatorVisibility="None">
                    <ListView.Footer/>
                </ListView>
            </StackLayout>
            <StackLayout Grid.Row="1" Orientation="Horizontal" HeightRequest="50">
                <Entry Text="{Binding CurrentMessageText}" Placeholder="{Binding MessageTextPlaceHolder}" HorizontalOptions="FillAndExpand"/>
                <Button Text="SEND" Command="{Binding SendMessageCommand}"/>
            </StackLayout>
        </Grid>
    </ContentPage.Content>
</ContentPage>
2个回答

25

试一下这个:

<Button
    Text="Hello!"
    Command="{Binding Path=BindingContext. TestCommand, Source={x:Reference Name=MessageListPage}}"
    CommandParameter="Hello" />

您需要为该页面提供一个名为x:Name,值为MessageListPage的属性,这会稍微破坏一下您的纯MVVM,但由于 Xamarin XAML 不支持相对绑定(就我所知..),所以这是可行的方法。


谢谢尝试!但是我在使用x:Reference时遇到了一个错误:找不到x:Reference的MarkupExtension。 - Raven
很奇怪,它应该可以工作。你可以尝试这个错误的解决方法:https://forums.xamarin.com/discussion/comment/191390/#Comment_191390 - Gerald Versluis
你应该给你的ListView一个x:Name,例如:<ListView x:Name="MessageListPage"。 - eakgul
你不需要将x:name引用添加到ListView,而是要添加到页面上(根据之前的评论)吗? - trevorgk
只是不要忘记写“Name =” - Joe B
显示剩余2条评论

1

不要将数据模板声明为内容字典中的静态资源,而是将数据模板放在列表本身的项模板中。

我不确定底层发生了什么,但似乎当数据模板被声明为静态资源时,它与页面的绑定上下文没有关联。这意味着当您离开并返回页面或更改列表视图的内容时,可能会出现渲染项更新的问题。

这将使您能够将按钮命令绑定到父级,并停止任何离开和重新访问页面时的问题。

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="MobileMobile.Views.MobileMessageListView"
    Title="Message List"
    NavigationPage.BarBackgroundColor="#FF9100"
    NavigationPage.BarTextColor="White"
    xmlns:ViewSwitchers="clr-namespace:MobileMobile.ViewSwitchers;assembly=MobileMobile"
    xmlns:ViewCells="clr-namespace:MobileMobile.ViewCells;assembly=MobileMobile"
    xmlns:Extensions="clr-namespace:MobileMobile.Extensions;assembly=MobileMobile"
    x:Name="DeclareYourCodeBehindHereOrDeclareAViewModel"
    >

<ContentPage.Resources>
    <ResourceDictionary>
        <ViewSwitchers:MobileMessageTemplateSwitcher x:Key="MobileMessageTemplateSwitcher" BotMessageDataTemplate="{StaticResource botMessageDataTemplate}" />
    </ResourceDictionary>
</ContentPage.Resources>

<ContentPage.Content>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <StackLayout Grid.Row="0" Orientation="Vertical" x:Name="MainViewStack">
            <ListView
                    CachingStrategy="RecycleElement"
                    BackgroundColor="Transparent"
                    IsPullToRefreshEnabled="true"
                    RefreshCommand="{Binding RefreshCommand}"
                    ItemsSource="{Binding Messages}"
                    HasUnevenRows="true"
                    IsRefreshing="{Binding IsLoading, Mode=OneWay}"
                    SeparatorVisibility="None">
                <ListView.ItemTemplate>
<DataTemplate x:Key="botMessageDataTemplate">
            <ViewCell>
                <Button Text="Hello!" Command="{Binding Source={x:Reference DeclareYourCodeBehindHereOrDeclareAViewModel}, Path=BindingContext.CommandName}" CommandParameter="Hello"/>
            </ViewCell>
        </DataTemplate>
                </ListView.ItemTemplate>
                <ListView.Footer/>
            </ListView>
        </StackLayout>
        <StackLayout Grid.Row="1" Orientation="Horizontal" HeightRequest="50">
            <Entry Text="{Binding CurrentMessageText}" Placeholder="{Binding MessageTextPlaceHolder}" HorizontalOptions="FillAndExpand"/>
            <Button Text="SEND" Command="{Binding SendMessageCommand}"/>
        </StackLayout>
    </Grid>
</ContentPage.Content>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接