Basically, I have a ListView with a DataTemplate Selector that uses a particular DataTemplate basing on the ListView item.
Now, in the DataTemplate - I have a button w/ a command that should be binded on the ViewModel of the Parent (or the ListView) itself.
Note that I only want to bind the Command property of the button as the Text and other properties would need to be binded to the current binding Context of the button.
The BindingContext of the DataTemplate is the ListView Item bindingContext (Message Model in this case) but I want to be able to bind just a specific button in the data template to the viewmodel of the parent listView.
How do I do that?
<?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>
Try this:
<Button
Text="Hello!"
Command="{Binding Path=BindingContext. TestCommand, Source={x:Reference Name=MessageListPage}}"
CommandParameter="Hello" />
You would have to give the Page an x:Name
property with the value MessageListPage
, so it messes with your pure MVVM a bit, but since Xamarin XAML doesn't support relative binding (as far as I know..) this is the way to go.
Instead of declaring the datatemplate as a static resource in a content dictionary, put the datatemplate in the itemtemplate of the list itself.
I'm not 100% sure of what's going on under the hood, but it would appear that the datatemplate is not associated with the binding context of the page when declared as a static resource. This means that when you leave and return to the page or change the contents of the listview then you may have issues rendering the update to the items.
This will enable you to bind your button command to the parent but also stop any problems if you leave and revisit the page
<?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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With