2016-08-12 54 views
3

視圖模型:的SelectedItem BindablePicker的不是可綁定stackLayout容器內工作在MvvmCross + xamarin形式

List<PictureModel> _pages; 
    public List<PictureModel> Pages 
    { 
     get 
     { 
      return _pages; 
     } 
     set 
     { 
      _pages = value; 
      RaisePropertyChanged(() => Pages); 
      CurrentPage = Pages.FirstOrDefault(); 
     } 
    } 

    private AttributeValue _selectedAttributeValue; 

    public AttributeValue SelectedAttributeValue 
    { 
     get { return _selectedAttributeValue; } 
     set 
     { 
      _selectedAttributeValue = value; 
      RaisePropertyChanged(() => SelectedAttributeValue); 
      SelectedAttributeCommand.Execute(null); 

     } 
    } 

    public ICommand SelectedAttributeCommand 
    { 
     get 
     { 
      //return new MvxCommand(() => ShowViewModel<ReviewsPageViewModel>()); 
      return new MvxCommand(() => 
      { 
       ChangePresentation(new MvxClosePresentationHint(new ProductListPageViewModel())); 
      }); 

     } 
    } 

MY XAML文件:

<controls:AwesomeWrappanel HorizontalOptions="CenterAndExpand"  Orientation="Horizontal" ItemsSource="{Binding ProductDeatil.ProductAttributes}" Spacing="10"> 
     <controls:AwesomeWrappanel.ItemTemplate> 
       <DataTemplate> 
         <controls:BindablePicker ItemsSource="{Binding Values}" 
         DisplayProperty="Name" Title="{Binding Name}" 
         SelectedIndex="0" SelectedItem="{Binding 
         SelectedAttributeValue, Mode=TwoWay}" />   
       </DataTemplate> 
     </controls:AwesomeWrappanel.ItemTemplate> 
</controls:AwesomeWrappanel> 

BindablePicker:

public class BindablePicker : Picker 
{ 
    public BindablePicker() 
    { 
     this.SelectedIndexChanged += OnSelectedIndexChanged; 
    } 


    public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create("SelectedItem", typeof(object), typeof(BindablePicker), null, BindingMode.TwoWay, null, new BindableProperty.BindingPropertyChangedDelegate(BindablePicker.OnSelectedItemChanged), null, null, null); 
    public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create("ItemsSource", typeof(IEnumerable), typeof(BindablePicker), null, BindingMode.TwoWay, null, new BindableProperty.BindingPropertyChangedDelegate(BindablePicker.OnItemsSourceChanged), null, null, null); 
    public static readonly BindableProperty DisplayPropertyProperty = BindableProperty.Create("DisplayProperty", typeof(string), typeof(BindablePicker), null, BindingMode.TwoWay, null, new BindableProperty.BindingPropertyChangedDelegate(BindablePicker.OnDisplayPropertyChanged), null, null, null); 

    public IList ItemsSource 
    { 
     get { return (IList)base.GetValue(BindablePicker.ItemsSourceProperty); } 
     set { base.SetValue(BindablePicker.ItemsSourceProperty, value); } 
    } 

    public object SelectedItem 
    { 
     get { return base.GetValue(BindablePicker.SelectedItemProperty); } 
     set 
     { 
      base.SetValue(BindablePicker.SelectedItemProperty, value); 
      if (ItemsSource.Contains(SelectedItem)) 
      { 
       SelectedIndex = ItemsSource.IndexOf(SelectedItem); 
      } 
      else 
      { 
       SelectedIndex = -1; 
      } 
     } 
    } 

    public string DisplayProperty 
    { 
     get { return (string)base.GetValue(BindablePicker.DisplayPropertyProperty); } 
     set { base.SetValue(BindablePicker.DisplayPropertyProperty, value); } 
    } 

    private void OnSelectedIndexChanged(object sender, EventArgs e) 
    { 
     this.SelectedItem = ItemsSource[SelectedIndex]; 
    } 


    private static void OnSelectedItemChanged(BindableObject bindable, object oldValue, object newValue) 
    { 
     BindablePicker picker = (BindablePicker)bindable; 
     picker.SelectedItem = newValue; 
     if (picker.ItemsSource != null && picker.SelectedItem != null) 
     { 
      int count = 0; 
      foreach (object obj in picker.ItemsSource) 
      { 
       if (obj == picker.SelectedItem) 
       { 
        picker.SelectedIndex = count; 
        break; 
       } 
       count++; 
      } 
     } 
    } 

    private static void OnDisplayPropertyChanged(BindableObject bindable, object oldValue, object newValue) 
    { 
     BindablePicker picker = (BindablePicker)bindable; 
     picker.DisplayProperty = (string)newValue; 
     loadItemsAndSetSelected(bindable); 

    } 
    private static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue) 
    { 
     var picker = (BindablePicker)bindable; 
     picker.ItemsSource = (IList)newValue; 

     var oc = newValue as INotifyCollectionChanged; 

     if (oc != null && !PickerLookup.ContainsKey(oc)) 
     { 
      oc.CollectionChanged += Oc_CollectionChanged; 
      PickerLookup.Add(oc, new WeakReference(picker)); 
     } 

     loadItemsAndSetSelected(bindable); 
    } 

    private static readonly Dictionary<INotifyCollectionChanged, WeakReference> PickerLookup = new Dictionary<INotifyCollectionChanged, WeakReference>(); 

    private static void Oc_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     var oc = (INotifyCollectionChanged)sender; 

     if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      var picker = (BindablePicker)PickerLookup[oc].Target; 

      foreach (var newItem in e.NewItems) 
      { 
       var value = string.Empty; 
       if (picker.DisplayProperty != null) 
       { 
        var prop = newItem.GetType().GetRuntimeProperties().FirstOrDefault(p => string.Equals(p.Name, picker.DisplayProperty, StringComparison.OrdinalIgnoreCase)); 

        if (prop != null) 
         value = prop.GetValue(newItem).ToString(); 
       } 
       else 
       { 
        value = newItem.ToString(); 
       } 

       picker.Items.Add(value); 
      } 
     } 
     else if (e.Action == NotifyCollectionChangedAction.Remove) 
     { 
      var picker = (BindablePicker)PickerLookup[oc].Target; 

      foreach (var newItem in e.OldItems) 
      { 
       var value = string.Empty; 
       if (picker.DisplayProperty != null) 
       { 
        var prop = newItem.GetType().GetRuntimeProperties().FirstOrDefault(p => string.Equals(p.Name, picker.DisplayProperty, StringComparison.OrdinalIgnoreCase)); 

        if (prop != null) 
         value = prop.GetValue(newItem).ToString(); 
       } 
       else 
       { 
        value = newItem.ToString(); 
       } 

       picker.Items.Remove(value); 
      } 
     } 
    } 

    static void loadItemsAndSetSelected(BindableObject bindable) 
    { 

     BindablePicker picker = (BindablePicker)bindable; 
     if (picker.ItemsSource as IEnumerable != null) 
     { 
      int count = 0; 
      foreach (object obj in (IEnumerable)picker.ItemsSource) 
      { 
       string value = string.Empty; 
       if (picker.DisplayProperty != null) 
       { 
        var prop = obj.GetType().GetRuntimeProperties().FirstOrDefault(p => string.Equals(p.Name, picker.DisplayProperty, StringComparison.OrdinalIgnoreCase)); 
        if (prop != null) 
        { 
         value = prop.GetValue(obj).ToString(); 
        } 
       } 
       else 
       { 
        value = obj.ToString(); 
       } 
       picker.Items.Add(value); 
       if (picker.SelectedItem != null) 
       { 
        if (picker.SelectedItem == obj) 
        { 
         picker.SelectedIndex = count; 
        } 
       } 
       count++; 
      } 
     } 
    } 
} 

這裏SelectedItem="{Binding SelectedAttributeValue}"不工作沒有得到在ViewModel價值。

回答

2

我已經得到解決

<控制:BindablePicker的ItemsSource = 「{綁定值}」 DisplayProperty = 「名稱」 標題= 「{綁定名稱}」 的SelectedItem =「{綁定路徑= BindingContext.SelectedAttributeValue源= {x:Reference Name = mypagename}}「/>

+0

2.3.4版本現在具有可綁定選擇器。它的工作更容易 – batmaci