컬렉션을 바인딩 할 수 있도록 Xamarin.Forms Picker를 확장하려고합니다. 빠른 검색 후이 페이지를 찾았습니다 : Picker Example 두 가지 좋은 예가 있습니다. 단지 &을 복사하는 것을 거부하면서 (학습 목적으로) 코드를 붙여 넣었습니다. 두 가지 예를 바탕으로 직접 작성했습니다.BindableProperty : 형식이 일치하지 않습니다.
광산이 작동하지 않는다면 거의 동일합니다.
ItemsSource에 컬렉션을 제공하지 않으면 모든 것이 정상적으로 작동합니다.
Xamarin.Forms.Xaml.XamlParseException: Position 9:32. Cannot assign property "ItemsSource": type mismatch between "Xamarin.Forms.Binding" and "System.Collections.IEnumerable"
선택기 :
public class BindablePicker : Picker
{
private static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create("ItemsSource", typeof(IEnumerable), typeof(BindablePicker), null, propertyChanged: OnItemsSourceChanged);
private static readonly BindableProperty SelectedItemProperty =
BindableProperty.Create("SelectedItem", typeof(object), typeof(BindablePicker));
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
public string DisplayMember { get; set; }
private static void OnItemsSourceChanged(BindableObject bindable, Object oldValue, Object newValue)
{
var newval = newValue as IEnumerable; //Had to implement this because of the non-generic .Create() method expects Object as param.
var picker = bindable as BindablePicker;
if (picker != null)
{
picker.Items.Clear();
if (newval == null) return;
foreach (var item in newval)
{
if (string.IsNullOrEmpty(picker.DisplayMember))
{
picker.Items.Add(item.ToString());
}
else
{
var prop = item.GetType()
.GetRuntimeProperties()
.FirstOrDefault(p => string.Equals(p.Name, picker.DisplayMember, StringComparison.OrdinalIgnoreCase));
picker.Items.Add(prop.GetValue(item).ToString());
}
}
}
}
private void OnSelectedIndexChanged(object sender, EventArgs args)
{
if (SelectedIndex < 0 || SelectedIndex > Items.Count - 1)
{
SelectedItem = null;
}
else
{
SelectedItem = ItemsSource.ItemOf(SelectedIndex); //ItemOf is an extension method I made for IEnumerable (has to be tested).
}
}
}
뷰 모델 (부품) :
public class HomePageViewModel : ViewModelBase
{
//In the app this is populated with a List<Person>.
public IEnumerable<Person> People { get; set; }
}
XAML :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:TestApp.Controls;assembly=TestApp"
x:Class="TestApp.Views.HomePage">
<ContentPage.Content>
<StackLayout>
<controls:BindablePicker ItemsSource="{Binding People}"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
주 나는 다음과 같은 오류가 모음을 할당 할 때마다 lin에서 첫 번째 예제 선택기 ked 페이지는 제공된 VM/View 설정과 함께 작동합니다.
필자도 아직 끝나지 않았습니다. 여전히 SelectedItem 속성에 TwoWay 바인딩을 제공하고 ObservableCollection을 지원하려고합니다.
네,