Hi All,
I'm hoping for some guidance on the following, would appreciate any contribution to help find the appropriate methodology:
I have a listview in a ContentPage that uses DataTemplateSelector to define the DataTemplate for a particular Item Type within the Listview:
<ContentPage.Resources>
<ResourceDictionary>
<local:RFIDataTemplateSelector x:Key="RFIDataTypeTemplateSelector"></local:RFIDataTemplateSelector>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<ListView x:Name="rfiListView"
ItemsSource="{Binding RFIs}"
ItemTemplate="{StaticResource RFIDataTypeTemplateSelector}"
SelectionMode="None"
HasUnevenRows="True"
Grid.Column="0"
Grid.Row="0">
</ListView>
</StackLayout>
</ContentPage.Content>
The DataTemplateSelector is as follows:
public class RFIDataTemplateSelector : DataTemplateSelector
{
private readonly DataTemplate ImageDataTemplate;
private readonly DataTemplate SingleLineTextDataTemplate;
private readonly DataTemplate MultiLineTextDataTemplate;
private readonly DataTemplate PickerDataTemplate;
private readonly DataTemplate NumberDataTemplate;
public RFIDataTemplateSelector()
{
this.ImageDataTemplate = new DataTemplate(typeof(ImageViewCell));
this.SingleLineTextDataTemplate = new DataTemplate(typeof(SingleLineTextViewCell));
this.MultiLineTextDataTemplate = new DataTemplate(typeof(EditorViewCell));
this.PickerDataTemplate = new DataTemplate(typeof(PickerViewCell));
this.NumberDataTemplate = new DataTemplate(typeof(NumberViewCell));
}
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
var rfiDto = item as RFIDto;
if (rfiDto == null) return null;
switch (rfiDto.DataType)
{
case 0:
return ImageDataTemplate;
case 1:
return SingleLineTextDataTemplate;
case 2:
return MultiLineTextDataTemplate;
case 4:
return PickerDataTemplate;
case 13:
return NumberDataTemplate;
}
return null;
}
}
And ViewModel for ContentPage with ListView:
public EditRFIsViewModel(INavigationService navigationService) : base(navigationService)
{
}
private ObservableCollection<RFIDto> rfis;
public ObservableCollection<RFIDto> RFIs
{
get { return rfis; }
set { SetProperty(ref rfis, value); }
}
An example of one of the DataTemplates in a seperate file:
<ViewCell x:Class="xxxx.Prism.Helpers.Views.ImageViewCell">
<ViewCell.View>
<StackLayout>
<Label Text="{Binding Display}" TextColor="#ea5c2d" Margin="10,10,10,0" />
<Button Text="{Binding Description}"
Margin="10,0,10,10">
<Button.Behaviors>
<b:EventToCommandBehavior EventName="Clicked"
Command="{Binding ImageSelectedCommand}" />
</Button.Behaviors>
</Button>
</StackLayout>
</ViewCell.View>
</ViewCell>
If I place a Command (ImageSelectedCommand) in the RFIDto I can call the command via the Button in the DataTemplate but really I want to call the Command within the EditRFIsViewModel.
The follwing works:
public class RFIDto : BindableBase
{
public DelegateCommand ImageSelectedCommand { get; set; }
public RFIDto(IJobService jobService)
{
ImageSelectedCommand = new DelegateCommand(ImageSelected);
}
private async void ImageSelected()
{
}
}
I've found the following which seems to suggest the methodology but I'm struggling as I'm fairly new to Xamarin and don't really understand ViewCell.ContextActions and MenuItem Commands and how to translate that to the Button Command I need.
A search engine search for "Xamarin.Forms ListView Advanced Guide With MVVM" will show the tutorial as I can't post a link.
Can anyone offer any guidance to wire the DataTemplate Button Command to a ViewModel Command as follows?
public DelegateCommand ImageSelectedCommand { get; set; }
public EditRFIsViewModel(INavigationService navigationService) : base(navigationService)
{
ImageSelectedCommand = new DelegateCommand(ImageSelected);
}
private ObservableCollection<RFIDto> rfis;
public ObservableCollection<RFIDto> RFIs
{
get { return rfis; }
set { SetProperty(ref rfis, value); }
}
private async void ImageSelected()
{
}
Thanks in advance
M