2015-03-28 4 views
5

Я пытаюсь создать собственный сборщик с 3 компонентами. Я следил за учебником на сайте Xamarin here. Я получил контроль над работой, за исключением случаев, когда я нажимаю кнопку «Готово» на сборщике (это кнопка по умолчанию). Я получаю следующее исключение:Пытается создать собственный сборщик в форматах Xamarin

System.InvalidCastException: Невозможно наложить объект типа 'myproj.iOS.MyPickerModel' на тип 'Xamarin.Forms.Platform.iOS.PickerRenderer + PickerSource'.

Вот мой код:

В общей Proj:

public class MyPicker: Picker {} 

В IOS Proj:

[assembly: ExportRenderer(typeof(MyPicker), typeof(MyPickerRenderer))] 

public class MyPickerRenderer: PickerRenderer 
{ 
    // Override the OnElementChanged method so we can tweak this renderer post-initial setup 
    protected override void OnElementChanged(ElementChangedEventArgs<Picker> e) 
    { 
     base.OnElementChanged(e); 

     if (Control != null) 
     { 
      var picker = (UIPickerView)this.Control.InputView; 
      picker.BackgroundColor = UIColor.White; 
      picker.Model = new MyPickerModel(); 
     } 

И Model:

public class MyPickerModel : UIPickerViewModel 
{ 
    private string[] array1 = new string [] { 
     "1","2","3","4" 
    }; 
    private string[] array2 = new string [] { 
     "1a","2a","3a","4a" 
    }; 

    private string[] array3 = new string [] { 
     "a","b","c","d" 
    }; 

    public override nint GetComponentCount (UIPickerView pickerView) 
    { 
     return 3; 
    } 

    public override nint GetRowsInComponent (UIPickerView pickerView, nint component) 
    { 
     // Returns 
     switch (component) { 
      case 0: return array1.Length; 
      case 1: return array2.Length; 
      case 2: return array3.Length; 
      default:break; 
     } 
     return 0; 
    } 

    public override string GetTitle (UIPickerView pickerView, nint row, nint component) 
    { 
     // Returns 
     switch (component) 
     { 
      case 0: return array1[row]; 
      case 1: return array2[row]; 
      case 2: return array3[row]; 
      default: break; 
     } 
     return null; 
    } 

    public override nfloat GetComponentWidth (UIPickerView pickerView, nint component) 
    { 
     switch (component) 
     { 
      case 0: return 100.0f; 
      case 1: return 100.0f; 
      case 2: return 100.0f; 
      default: break; 
     } 

     return 0; 
    } 

    public override nfloat GetRowHeight (UIPickerView pickerView, nint component) 
    { 
     return 40f; 
    } 
} 

И, наконец, моя страница:

public class MyPage : ContentPage 
{ 
    public MyPage() 
    { 
     MyPicker picker = new MyPicker 
     { 
      Title = "Color", 
      VerticalOptions = LayoutOptions.CenterAndExpand 
     }; 

     picker.SelectedIndexChanged += (sender, args) => 
     { 

     }; 

     var mainLayout = new StackLayout 
     { 
      Orientation = StackOrientation.Vertical, 
      Children = 
      { 
       picker 

      } 
     }; 


     // Accomodate iPhone status bar. 
     this.Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0); 
     this.BackgroundImage = "background.png"; 

     // Build the page. 
     this.Content = mainLayout; 
    } 
} 

Я не понимаю, почему его пытаются бросить MyPickerModel к PickerRenderer + PickerSource

Спасибо!

ответ

1

Не знаю, как работает IOS, но выглядит, как мой андроид версия есть показывает, что вам нужно:

Моего basePicker выглядит следующим образом:

public class BaseBindablePicker : Picker 
{ 
    public static readonly BindableProperty BackgroundColor= 
    BindableProperty.Create<BaseBindablePicker, Color>(p => p.BackgroundColor, Color.Default); 

    public Color ColorBackground 
    { 
     get { return (Color)base.GetValue(BackgroundColor); } 
     set { base.SetValue(BackgroundColor, value); } 
    } 
} 

Моей платформа конкретного вид выглядит следующим образом:

[assembly: ExportRenderer(typeof(BaseBindablePicker), typeof(SimpleEID.Android.Shared.CustomRender.AndroidPicker))] 

public class AndroidPicker : PickerRenderer 
{  
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Picker> e) 
    { 
     base.OnElementChanged(e); 

     var pick = (BaseBindablePicker)this.Element; 
     this.Control.SetBackgroundColor(pick.BackColor.ToAndroid()); 
    } 
} 

Как правило, вам необходимо изменить

var picker = (UIPickerView)this.Control.InputView; 

быть

var picker = (MyPicker)this.Element; 

Тогда просто refence то, что вам нужно от там, возможно, добавить ссылку на вашу модель

4

Вы были почти там ... Просто создать новый экземпляр UIPickerView, назначить свой пользовательский (MyPickerModel), а затем назначьте UIPickerView на номер Control.InputView. OnElementChanged в вашем рендерере будет выглядеть следующим образом:

protected override void OnElementChanged(ElementChangedEventArgs<Picker> e) 
{ 
    base.OnElementChanged(e); 

    if (Control != null) 
    { 
     var myPickerModel = new MyPickerModel(); 
     var myPickerView = new UIPickerView 
     { 
      Model = myPickerModel 
     }; 
     //Assign your picker view 
     Control.InputView = myPickerView; 

     //You can also create an event in your model to react on user actions like e.g. "SelectedValueChanged"... 
     myPickerModel.SelectedValueChanged += (sender, eventArgs) => 
     { 
      //...to set the selected value as title of the picker element 
      e.NewElement.Title = myPickerModel.SelectedValue; 
     }; 
    } 
} 
Смежные вопросы