升级自定义视图列表mvvmcross touch

时间:2013-10-10 15:34:16

标签: xamarin.ios mvvmcross

您好我正在尝试将我们的ios应用从mvvmcross v1升级到v3。我无法弄清楚如何使我的自定义按钮工作。

我的观点ViewDidLoad它是与按钮行绑定的按钮项

public override void ViewDidLoad()
{
    base.ViewDidLoad();
    SortingView.ViewModel = ViewModel;
    _shown = false;

    // Setup View Animatons 
    Buttons.OnClick = () => { AnimationTransition = ViewTransitionAnimation.TransitionFade; };

    TopRightButton.TouchDown +=
          (sender, args) => {
            AnimationTransition = ViewTransitionAnimation.TransitionCrossDissolve; 
          };

    // Setup Bindings
    this.AddBindings(
     new Dictionary<object, string>
         {
             {this.BackgroundImage, "{'ImageData':{'Path':'BackgroundImage','Converter':'ImageItem'}}"},
             {this.TopbarBackground, "{'ImageData':{'Path':'TopBarImage','Converter':'ImageItem'}}"},
             {this.TopLogo, "{'ImageData':{'Path':'Logo','Converter':'ImageItem'}}"},
             {this.Buttons, "{'ItemsSource':{'Path':'ButtonItems'}}"},
             {this.SlideMenu, "{'ItemsSource':{'Path':'VisibleViews'}}"},
             {
                 this.SortingView,
                 "{'ItemsSource':{'Path':'CategoriesName'},'SelectedGroups':{'Path':'SelectedGroups'},'ForceUbracoUpdateAction':{'Path':'ForceUbracoUpdateAction'}}"
             },
            {this.SettingsButton, "{'TouchDown':{'Path':'TopRightButtonClick'},'Hide':{'Path':'HideTopbarButton'},'ImageData':{'Path':'TopButtonImage','Converter':'ImageItem'}}" },
            {this.TopRightButton, "{'TouchDown':{'Path':'SecondaryButtonButtonPushed'},'Hide':{'Path':'HideTopbarButton2'},'ImageData':{'Path':'SettingsButtonImage','Converter':'ImageItem'}}" }
        });

    // Perform any additional setup after loading the view, typically from a nib.
    NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidBecomeActiveNotification, ReEnableSlideMenu);
    this.SortingView.Hidden=true;
    ViewModel.SettingButtonEvent += HandleSettingButtonPushed;
}

这是我的自定义控件&#34; ButtonRow

[Register("ButtonRow")]
public class ButtonRow : CustomListViewController
{
    private int _width = 0;
    private UIImage _backgroundImage = null;
    public ButtonRow(IntPtr handle)
        : base(handle)
    {
        _width = (int)this.Frame.Width;
        UseImageAsIcon = false;
        FontSize=0;
    }

    public bool UseImageAsIcon { get; set; }

    public UIImage BackgroundImage
    {
        get { return _backgroundImage; }
        set { _backgroundImage = value; }
    }

    public int FontSize
    {
        get;set;
    }

    private Action _onClickAction;

    private int _spacing = 0;

    public Action OnClick
    {
        get
        {
            return _onClickAction;
        }

        set
        {
            _onClickAction = value;
        }
    }

    /// <summary>
    /// The add views.
    /// </summary>
    /// custom implementation for adding views to the button row
    protected override void AddViews()
    {
        if (ItemsSource == null)
        {
            Hidden = true;
            return;
        }

        base.AddViews();

        foreach (UIView uiView in Subviews)
        {

            uiView.RemoveFromSuperview();
        }

        if (ItemsSource.Count == 0)
        {
            Hidden = true;
            return;
        }

        if (_backgroundImage != null)
        {
            var frame = new RectangleF(0, 0, Frame.Width, Frame.Height);

            var background = new UIImageView(frame) { Image = _backgroundImage };

            AddSubview(background);
        }
        _width = _width - ((ItemsSource.Count - 1) * Spacing);

        var buttonWidth = (int)Math.Ceiling (((double)_width) / ItemsSource.Count);

        int index = 0;
        foreach (ViewItemModel item in ItemsSource)
        {
            // creating custom button with needed viewmodel, nib etc is loaded in the class constructor
            var button = new ButtonWithLabel(item, OnClick);

            if (FontSize > 0)
            {
                button.FontSize(FontSize);
            }


            if (UseImageAsIcon)
            {
                button.AddBindings(
                    new Dictionary<object, string>
                    {
                    { button, "{'IconLabel':{'Path':'Title'},'TitleFontColor':{'Path':'TitleFontColor'}}" },
                    { button.icon, "{'ImageData':{'Path':'ImageIcon','Converter':'ImageItem'}}" }
                });
            }
            else
            {
                // bindings created between the button and its viewmodel

                button.AddBindings(
                    new Dictionary<object, string>
                    {
                    {button, "{'Label':{'Path':'Title'},'TitleFontColor':{'Path':'TitleFontColor'},'BackgroundColor':{'Path':'BackgroundColor'}}" },
                    {button.Background, "{'ImageData':{'Path':'ImageIcon','Converter':'ImageItem'}}" }
                });
                button.icon.Hidden = true;
            }

            // new frame of button is set, as the number of buttons is dynamic
            int x = index == 0 ? 0 : index * (buttonWidth + Spacing);
            button.SetFrame(new RectangleF(x, 0, buttonWidth, Frame.Height));


            // the view of the button is added to the buttonrow view
            AddSubview(button.View);

            index++;
        }
    }

    public int Spacing
    {
        get
        {
            return this._spacing;
        }
        set
        {
            this._spacing = value;
        }
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
    }

    public override void Cleanup()
    {
        if(Subviews!=null)
        {
            foreach (var view in Subviews)
            {
                view.RemoveFromSuperview();
            }
        }
        if(_backgroundImage!=null)
        {
            _backgroundImage.Dispose();
        }

        ItemsSource = null;
    }

}

这是我的CustomListViewController

public class CustomListViewController: UIView
{

    private IList _itemsSource;
    private CustomViewSource _viewSource;

    public CustomListViewController(MvxShowViewModelRequest showRequest)
    {
        ShowRequest = showRequest;
    }

    protected CustomListViewController()
    {
    }
    public CustomListViewController(IntPtr handle)
        : base(handle)
    {
    }
    public bool IsVisible
    {
        get
        {
           return this.IsVisible;
        }
    }

    public IList ItemsSource
    {
        get { return _itemsSource; }
        set { _itemsSource = value; if(value!=null){CreateViewSource(_itemsSource); }}
    }

    public virtual void CreateViewSource(IList items)
    {

        if (_viewSource == null)
        {
            _viewSource = new CustomViewSource();
            _viewSource.OnNewViewsReady += FillViews;
        }
        _viewSource.ItemsSource = items;
    }

    private void FillViews(object sender, EventArgs e)
    {
        AddViews();
    }

    protected virtual void AddViews()
    {

        // get views from source and do custom allignment
    }

    public virtual void Cleanup()
    {
        if(_viewSource!=null)
        {
            _itemsSource.Clear();
            _itemsSource=null;
        _viewSource.OnNewViewsReady -= FillViews;
        _viewSource.ItemsSource.Clear();
        _viewSource.ItemsSource = null;
        _viewSource=null;
        }
    }

    public MvxShowViewModelRequest ShowRequest { get;
        private set;
    }        

}

我的CustomViewSource

public class CustomViewSource
{
    private IList _itemsSource;

    private List<UIView> _views=new List<UIView>();

    public event EventHandler<EventArgs> OnNewViewsReady;

    public CustomViewSource ()
    {
    }

    public List<UIView> Views { get { return _views; } }

    public virtual IList ItemsSource
    {
        get { return _itemsSource; }
        set
        {
     //       if (_itemsSource == value)
       //         return;

            var collectionChanged = _itemsSource as INotifyCollectionChanged;
            if (collectionChanged != null)
                collectionChanged.CollectionChanged -= CollectionChangedOnCollectionChanged;
            _itemsSource = value;
            collectionChanged = _itemsSource as INotifyCollectionChanged;
            if (collectionChanged != null)
                collectionChanged.CollectionChanged += CollectionChangedOnCollectionChanged;
            ReloadViewData();
        }
    }

    protected object GetItemAt(int position)
    {
        if (ItemsSource == null)
            return null;

        return ItemsSource[position];
    }

    protected void CollectionChangedOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
    {
        ReloadViewData();
    }

    protected virtual void ReloadViewData()
    {
        if(ItemsSource==null){return;}
        foreach (var VARIABLE in ItemsSource)
        {
            //call create view and add it to Views
        }

        //event new views created
        if(OnNewViewsReady!=null)
            OnNewViewsReady(this,new EventArgs());

    }

    protected virtual UIView CreateUIView(int position)
    {
        UIView view = null;
        /*
        //create view from nib
        UIView newView=null;
        return newView;
         * */
        return view;
    }

}

任何人都有关于如何在mvvmcross v3中完成这项工作的线索?

我想这样做,我可以添加x个按钮并加载nib文件中的按钮。看过Kittens集合视图的例子,但还没弄明白如何使它适用于我的buttonRow,不确定collectionView是否适合用作base。

1 个答案:

答案 0 :(得分:0)

显示列表的最常用方法是使用UITableView

周围有很多样本展示了如何在MvvmCross中加载这些:


在您的情况下,看起来前一个编码器已经实现了某种自定义布局的自定义控件。将其改编为v3并不是特别困难,但是您需要仔细阅读并理解之前的代码及其工作原理(这与MvvmCross无关 - 它只是应用程序UI代码)。

在iOS中处理自定义视图的一个示例是N = 32教程 - http://slodge.blogspot.co.uk/2013/06/n32-truth-about-viewmodels-starring.html