您好我正在尝试将我们的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。
答案 0 :(得分:0)
显示列表的最常用方法是使用UITableView
。
周围有很多样本展示了如何在MvvmCross中加载这些:
在您的情况下,看起来前一个编码器已经实现了某种自定义布局的自定义控件。将其改编为v3并不是特别困难,但是您需要仔细阅读并理解之前的代码及其工作原理(这与MvvmCross无关 - 它只是应用程序UI代码)。
在iOS中处理自定义视图的一个示例是N = 32教程 - http://slodge.blogspot.co.uk/2013/06/n32-truth-about-viewmodels-starring.html