私は自分のViewModel内でコマンドを使用して、リストビューと対話できるようにしたいと考えていました。私はEventToCommandBehaviorのフォームの例を見ました。私は自分のプロジェクト内でコードを複製しようとしましたが、何らかの理由でそれを動作させることができません。 Sogeti.Core.Behaviorsフォルダ内Xamarin Forms ListViewコマンドからVMへEventToCommandBehaviorを使用する
BehaviorBase.cs Sogeti.Core.Behaviorsフォルダ内
using System;
using Xamarin.Forms;
namespace Sogeti.Core
{
public class BehaviorBase<T> : Behavior<T> where T : BindableObject
{
public T AssociatedObject { get; private set; }
protected override void OnAttachedTo(T bindable)
{
base.OnAttachedTo(bindable);
AssociatedObject = bindable;
if (bindable.BindingContext != null)
{
BindingContext = bindable.BindingContext;
}
bindable.BindingContextChanged += OnBindingContextChanged;
}
protected override void OnDetachingFrom(T bindable)
{
base.OnDetachingFrom(bindable);
bindable.BindingContextChanged -= OnBindingContextChanged;
AssociatedObject = null;
}
void OnBindingContextChanged(object sender, EventArgs e)
{
OnBindingContextChanged();
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
BindingContext = AssociatedObject.BindingContext;
}
}
}
EventToCommandBehavior.cs
using System;
using System.Reflection;
using System.Windows.Input;
using Xamarin.Forms;
namespace Sogeti.Core
{
public class EventToCommandBehavior : BehaviorBase<View>
{
Delegate eventHandler;
public static readonly BindableProperty EventNameProperty = BindableProperty.Create("EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(EventToCommandBehavior), null);
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(EventToCommandBehavior), null);
public static readonly BindableProperty InputConverterProperty = BindableProperty.Create("Converter", typeof(IValueConverter), typeof(EventToCommandBehavior), null);
public string EventName
{
get { return (string)GetValue(EventNameProperty); }
set { SetValue(EventNameProperty, value); }
}
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public IValueConverter Converter
{
get { return (IValueConverter)GetValue(InputConverterProperty); }
set { SetValue(InputConverterProperty, value); }
}
protected override void OnAttachedTo(View bindable)
{
base.OnAttachedTo(bindable);
RegisterEvent(EventName);
}
protected override void OnDetachingFrom(View bindable)
{
DeregisterEvent(EventName);
base.OnDetachingFrom(bindable);
}
void RegisterEvent(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return;
}
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
if (eventInfo == null)
{
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't register the '{0}' event.", EventName));
}
MethodInfo methodInfo = typeof(EventToCommandBehavior).GetTypeInfo().GetDeclaredMethod("OnEvent");
eventHandler = methodInfo.CreateDelegate(eventInfo.EventHandlerType, this);
eventInfo.AddEventHandler(AssociatedObject, eventHandler);
}
void DeregisterEvent(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return;
}
if (eventHandler == null)
{
return;
}
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
if (eventInfo == null)
{
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't de-register the '{0}' event.", EventName));
}
eventInfo.RemoveEventHandler(AssociatedObject, eventHandler);
eventHandler = null;
}
void OnEvent(object sender, object eventArgs)
{
if (Command == null)
{
return;
}
object resolvedParameter;
if (CommandParameter != null)
{
resolvedParameter = CommandParameter;
}
else if (Converter != null)
{
resolvedParameter = Converter.Convert(eventArgs, typeof(object), null, null);
}
else
{
resolvedParameter = eventArgs;
}
if (Command.CanExecute(resolvedParameter))
{
Command.Execute(resolvedParameter);
}
}
static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue)
{
var behavior = (EventToCommandBehavior)bindable;
if (behavior.AssociatedObject == null)
{
return;
}
string oldEventName = (string)oldValue;
string newEventName = (string)newValue;
behavior.DeregisterEvent(oldEventName);
behavior.RegisterEvent(newEventName);
}
}
}
SelectedItemEventArgsToSelectedItemConverter:
何私が得たことはこれです。 Sogeti.Core.Convertersフォルダ内のcs
Sogeti.Core.ViewModelフォルダ内MyViewModel
using System;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Input;
using Xamarin.Forms;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Sogeti.Core
{
public class SogetistDetailsViewModel : SimpleViewModel
{
private Sogetist sogetist;
public ICommand ViewSelectedCommand { get; private set; }
public string FullName
{
get
{
return sogetist.Name + " " + sogetist.LastName;
}
}
public string Introduction
{
get
{
return sogetist.Introduction;
}
set
{
if (sogetist.Introduction != value)
{
sogetist.Introduction = value;
RaisePropertyChanged(() => Introduction);
}
}
}
public string Function
{
get
{
return sogetist.Function.Name;
}
set
{
if (value != sogetist.Function.Name)
{
sogetist.Function.Name = value;
RaisePropertyChanged(() => Function);
}
}
}
public string Skills
{
get
{
List<string> skills = sogetist.Skill.Select(x => x.Name).ToList();
return string.Join(", ", skills);
}
}
public string Image
{
get
{
return sogetist.Image;
}
set
{
if (value != sogetist.Image)
{
sogetist.Image = value;
RaisePropertyChanged(() => Image);
}
}
}
public SogetistDetailsViewModel() : this(new Sogetist())
{
}
public SogetistDetailsViewModel(Sogetist sogetist)
{
this.sogetist = sogetist;
Image = this.sogetist.Image;
ViewSelectedCommand = new Command<Sogetist>(OnViewSelected);
}
void OnViewSelected(Sogetist obj)
{
String a = obj.Name;
}
}
}
MainPage.xamlをSogeti名前空間内の
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="Sogeti.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:core="clr-namespace:Sogeti.Core;assembly=Sogeti.Core"
Title="Sogetist list">
<ContentPage.Resources>
<ResourceDictionary>
<core:SelectedItemEventArgsToSelectedItemConverter x:Key="SelectedItemConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<ListView x:Name="listView"
CachingStrategy="RecycleElement"
Footer="{Binding Count}"
IsPullToRefreshEnabled="True"
ItemsSource="{Binding .}">
<ListView.Behaviors>
<core:EventToCommandBehavior EventName="ItemSelected" Command="{Binding ViewSelectedCommand}" Converter="{StaticResource SelectedItemConverter}" />
</ListView.Behaviors>
<ListView.FooterTemplate>
<DataTemplate>
<ContentView BackgroundColor="#FF4411" Padding="0,5">
<Label FontSize="Micro"
HorizontalTextAlignment="Center"
Text="{Binding .,
StringFormat='{0} Sogetists'}"
TextColor="White"
VerticalTextAlignment="Center">
<Label.Triggers>
<DataTrigger Binding="{Binding .}"
TargetType="Label"
Value="1">
<Setter Property="Text" Value="{Binding ., StringFormat='{0} Sogetist'}" />
</DataTrigger>
</Label.Triggers>
</Label>
</ContentView>
</DataTemplate>
</ListView.FooterTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell Detail="{Binding Function}"
ImageSource="{Binding Image}"
Text="{Binding FullName}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
MainPage.Xaml.cs
using Xamarin.Forms;
using Sogeti.Core;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using System.Collections.ObjectModel;
using System.Linq;
namespace Sogeti
{
public partial class MainPage : ContentPage
{
private readonly BackendlessHandler backendless = new BackendlessHandler();
public ObservableCollection<SogetistDetailsViewModel> Sogetists { get; private set; }
public MainPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
if (Sogetists == null)
{
await LoadSogetistsAsync();
BindingContext = Sogetists;
}
}
private async Task LoadSogetistsAsync()
{
IsBusy = true;
try
{
var sogetistDetailsViewModelList = (await backendless.GetAllSogetistsAsync()).OrderBy(x => x.Name).Select(x => new SogetistDetailsViewModel(x));
Sogetists = new ObservableCollection<SogetistDetailsViewModel>(sogetistDetailsViewModelList);
}
catch (Exception ex)
{
await this.DisplayAlert("Error", "Failed to download sogetists: " + ex.Message, "OK");
}
finally
{
IsBusy = false;
}
}
}
}
これは多くのコードです。あなたが実際の質問、あなたがすでに試したこと、予想される結果、そして実際の結果が何であるかを記述すれば、より簡単になります。 – Krumelur