Exemplo n.º 1
0
        private DataBinding AddBinding(string propertyName, BindingMode mode = BindingMode.OneWay, string listPropertyName = null, View view = null, AdapterView commandParameterSelectedItemAdapterView = null)
        {
            string idName = (view != null) ? view.Id.ToString() : IdName(propertyName);
            int? resourceId = AndroidHelpers.FindResourceId(idName);
            if (view == null && resourceId.HasValue) view = rootView.FindViewById(resourceId.Value);
            if (view == null) return null;

            bool itemIsValue = false;
            string itemTemplateName = null, itemValueId = null;
            int? commandParameterListId = null;
            if (view.Tag != null)
            {
                // Get optional parameters from tag:
                // {Binding propertyName, Mode=OneWay|TwoWay|Command}
                // {List ItemsSource=listPropertyName, ItemIsValue=false|true, ItemTemplate=listItemTemplateName, ItemValueId=listItemValueId}
                // {CommandParameter ListId=<view Id>}
                // Defaults:
                //   propertyName is known by convention from view Id = <rootview prefix><propertyName>; the default for the rootview prefix is the rootview class name + "_".
                //   Mode = OneWay
                // Additional defaults for views derived from AdapterView (i.e. lists):
                //   ItemsSource = propertyName + "List"
                //   ItemIsValue = false
                //   ItemTemplate = ItemsSource + "Item"
                //   ItemValueId : if ItemIsValue = true then the default for ItemValueId = ItemTemplate
                string tag = view.Tag.ToString();
                if (tag != null && tag.Contains("{"))
                {
                    var match = Regex.Match(tag, @"({Binding\s+((?<assignment>[^,{}]+),?)+\s*})?(\s*{List\s+((?<assignment>[^,{}]+),?)+\s*})?(\s*{CommandParameter\s+((?<assignment>[^,{}]+),?)+\s*})?");
                    if (match.Success)
                    {
                        var gc = match.Groups["assignment"];
                        if (gc != null)
                        {
                            var cc = gc.Captures;
                            if (cc != null)
                            {
                                for (int i = 0; i < cc.Count; i++)
                                {
                                    string[] assignmentElements = cc[i].Value.Split('=');
                                    if (assignmentElements.Length == 1)
                                    {
                                        string value = assignmentElements[0].Trim();
                                        if (value != "") propertyName = value;
                                    }
                                    else if (assignmentElements.Length == 2)
                                    {
                                        string name = assignmentElements[0].Trim();
                                        string value = assignmentElements[1].Trim();
                                        switch (name)
                                        {
                                            case "Mode": Enum.TryParse<BindingMode>(value, true, out mode); break;
                                            case "ItemsSource": listPropertyName = value; break;
                                            case "ItemIsValue": Boolean.TryParse(value, out itemIsValue); break;
                                            case "ItemTemplate": itemTemplateName = value; break;
                                            case "ItemValueId": itemValueId = value; break;
                                            case "ListId":
                                                commandParameterListId = AndroidHelpers.FindResourceId(value);
                                                if (commandParameterSelectedItemAdapterView == null && commandParameterListId.HasValue) commandParameterSelectedItemAdapterView = rootView.FindViewById<AdapterView>(commandParameterListId.Value);
                                                break;
                                            default: throw new ArgumentException("Unknown tag binding parameter: " + name);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            var binding = new DataBinding
            {
                View = view,
                ResourceId = resourceId,
                Mode = mode,
                ViewModelPropertyInfo = viewModel.GetType().GetProperty(propertyName),
                CommandParameterListId = commandParameterListId,
                CommandParameterListView = commandParameterSelectedItemAdapterView
            };

            if (binding.View is AdapterView)
            {
                if (listPropertyName == null) listPropertyName = propertyName + "List";
                var pi = viewModel.GetType().GetProperty(listPropertyName);
                if (pi == null && binding.ViewModelPropertyInfo.PropertyType.GetInterface("IList") != null)
                {
                    listPropertyName = propertyName;
                    pi = binding.ViewModelPropertyInfo;
                    binding.ViewModelPropertyInfo = null;
                }
                binding.ViewModelListPropertyInfo = pi;

                pi = binding.View.GetType().GetProperty("Adapter", BindingFlags.Public | BindingFlags.Instance);
                if (pi != null)
                {
                    var adapter = pi.GetValue(binding.View);
                    if (adapter == null)
                    {
                        if (itemTemplateName == null) itemTemplateName = listPropertyName + "Item";
                        if (itemIsValue && itemValueId == null) itemValueId = itemTemplateName;
                        int? itemTemplateResourceId = AndroidHelpers.FindResourceId(itemTemplateName, AndroidHelpers.ResourceCategory.Layout);
                        int? itemValueResourceId = AndroidHelpers.FindResourceId(itemValueId);
                        if (itemTemplateResourceId.HasValue)
                        {
                            adapter = new DataBindableListAdapter<object>(layoutInflater, itemTemplateResourceId.Value, itemTemplateName + "_", itemValueResourceId, rootViewExtensionPoints);
                            pi.SetValue(binding.View, adapter);
                        }
                    }
                    binding.ListAdapter = adapter as IDataBindableListAdapter;
                }
            }

            switch (binding.Mode)
            {
                case BindingMode.TwoWay: AddTwoWayHandler(binding); break;
                case BindingMode.Command: AddCommandHandler(binding); break;
            }

            dataBindings.Add(idName, binding);
            return binding;
        }
Exemplo n.º 2
0
        private DataBinding AddBinding(BindingParameters bp)
        {
            object view = bp.View;
            View androidView = view as View;
            string propertyName = bp.ViewModelPropertyName;
            if (string.IsNullOrEmpty(propertyName)) throw new ArgumentNullException("ViewModelPropertyName");

            string idName = IdName(propertyName);
            int? resourceId;
            if (androidView != null)
            {
                string viewIdName = AndroidHelpers.FindResourceName(androidView.Id);
                if (viewIdName != idName) throw new ArgumentException(string.Format("View Id '{0}' does not match expected value '{1}'; adjust either the view Id or the ViewModelPropertyName binding parameter.", viewIdName, idName));
                resourceId = androidView.Id;
            }
            else
            {
                resourceId = AndroidHelpers.FindResourceId(idName);
            }

            if (view == null && resourceId.HasValue) view = androidView = rootView.FindViewById(resourceId.Value);
            if (view == null) return null;

            if (androidView != null && androidView.Tag != null) bp = ParseBindingParameters(androidView.Tag.ToString(), bp);

            string viewMemberName = bp.ViewMemberName;
            if ((bp.Mode == BindingMode.OneWay || bp.Mode == BindingMode.TwoWay) && bp.UpdateView == null && viewMemberName == null) ViewDefaultPropertyOrFieldName.TryGetValue(view.GetType().FullName, out viewMemberName);

            var viewModelPropertyInfo = (string.IsNullOrEmpty(propertyName) || propertyName == ".") ? null : viewModel.GetType().GetProperty(propertyName);
            AdapterView commandParameterSelectedItemAdapterView = bp.CommandParameterSelectedItemAdapterView;
            if (commandParameterSelectedItemAdapterView == null && bp.ListId.HasValue)
            {
                commandParameterSelectedItemAdapterView = rootView.FindViewById<AdapterView>(bp.ListId.Value);
            }

            var binding = new DataBinding
            {
                ViewProperty = new PropertyReference(view, viewMemberName, viewModelPropertyInfo != null ? viewModelPropertyInfo.PropertyType : null),
                ResourceId = resourceId,
                UpdateViewAction = bp.UpdateView,
                UpdateViewModelAction = bp.UpdateViewModel,
                Mode = bp.Mode,
                ViewModelPropertyInfo = viewModelPropertyInfo,
                CommandParameterListId = bp.ListId,
                CommandParameterListView = commandParameterSelectedItemAdapterView
            };

            string listPropertyName = bp.ListPropertyName;
            if (listPropertyName == null) listPropertyName = propertyName + "List";
            var pi = viewModel.GetType().GetProperty(listPropertyName);
            if (pi == null && binding.ViewModelPropertyInfo.PropertyType.GetInterface("IList") != null)
            {
                listPropertyName = propertyName;
                pi = binding.ViewModelPropertyInfo;
                binding.ViewModelPropertyInfo = null;
            }
            binding.ViewModelListPropertyInfo = pi;

            if (view is AdapterView)
            {
                pi = view.GetType().GetProperty("Adapter", BindingFlags.Public | BindingFlags.Instance);
                if (pi != null)
                {
                    var adapter = pi.GetValue(view);
                    if (adapter == null)
                    {
                        string itemTemplateName = bp.ListItemTemplateName ?? listPropertyName + "Item";
                        string itemValueId = (bp.ListItemIsValue && bp.ListItemValueId == null) ? itemTemplateName : bp.ListItemValueId;
                        int? itemTemplateResourceId = AndroidHelpers.FindResourceId(itemTemplateName, AndroidHelpers.ResourceCategory.Layout);
                        int? itemValueResourceId = AndroidHelpers.FindResourceId(itemValueId);
                        if (itemTemplateResourceId.HasValue)
                        {
                            adapter = new DataBindableListAdapter<object>(layoutInflater, itemTemplateResourceId.Value, itemTemplateName + "_", itemValueResourceId, rootViewExtensionPoints);
                            pi.SetValue(view, adapter);
                        }
                    }
                    binding.ListAdapter = adapter as IDataBindableListAdapter;
                }
            }

            switch (binding.Mode)
            {
                case BindingMode.TwoWay: AddTwoWayHandler(binding); break;
                case BindingMode.Command: AddCommandHandler(binding); break;
            }

            dataBindings.Add(idName, binding);
            return binding;
        }