Пример #1
0
        internal static NSIndexPath GetIndexPath(this Cell self)
        {
            if (self == null)
            {
                throw new ArgumentNullException("self");
            }

            NSIndexPath path;

            if (self.RealParent is ListView)
            {
                var section = 0;
                var til     = TemplatedItemsList <ItemsView <Cell>, Cell> .GetGroup(self);

                if (til != null)
                {
                    section = TemplatedItemsList <ItemsView <Cell>, Cell> .GetIndex(til.HeaderContent);
                }

                var row = TemplatedItemsList <ItemsView <Cell>, Cell> .GetIndex(self);

                path = NSIndexPath.FromRowSection(row, section);
            }
            else if (self.RealParent is TableView)
            {
                var tmPath = TableView.TableSectionModel.GetPath(self);
                path = NSIndexPath.FromRowSection(tmPath.Item2, tmPath.Item1);
            }
            else
            {
                throw new NotSupportedException("Unknown cell parent type");
            }

            return(path);
        }
Пример #2
0
        void OnNativeItemTapped(object sender, GestureEventArgs e)
        {
            var cell = (Cell)Control.SelectedItem;

            if (cell == null)
            {
                return;
            }

            Cell parentCell = null;

            if (Element.IsGroupingEnabled)
            {
                TemplatedItemsList <ItemsView <Cell>, Cell> til = TemplatedItemsList <ItemsView <Cell>, Cell> .GetGroup(cell);

                parentCell = til.HeaderContent;
            }

            _fromNative = cell.BindingContext;

            if (Element.IsGroupingEnabled)
            {
                Element.NotifyRowTapped(TemplatedItemsList <ItemsView <Cell>, Cell> .GetIndex(parentCell), TemplatedItemsList <ItemsView <Cell>, Cell> .GetIndex(cell));
            }
            else
            {
                Element.NotifyRowTapped(TemplatedItemsList <ItemsView <Cell>, Cell> .GetIndex(cell));
            }
        }
Пример #3
0
        async void OnViewChangeCompleted(object sender, SemanticZoomViewChangedEventArgs e)
        {
            if (e.IsSourceZoomedInView)
            {
                return;
            }

            // HACK: Technically more than one short name could be the same, this will potentially find the wrong one in that case
            var item = (string)e.SourceItem.Item;

            int index = Element.TemplatedItems.ShortNames.IndexOf(item);

            if (index == -1)
            {
                return;
            }

            TemplatedItemsList <ItemsView <Cell>, Cell> til = Element.TemplatedItems.GetGroup(index);

            if (til.Count == 0)
            {
                return;                 // FIXME
            }
            // Delay until after the SemanticZoom change _actually_ finishes, fixes tons of odd issues on Phone w/ virtualization.
            if (Device.Idiom == TargetIdiom.Phone)
            {
                await Task.Delay(1);
            }

            ScrollTo(til.ListProxy.ProxiedEnumerable, til.ListProxy[0], ScrollToPosition.Start, true, true);
        }
Пример #4
0
        static TemplatedItemsList <ItemsView <Cell>, Cell> GetGroup(object newContext, ListView lv)
        {
            int groupIndex = lv.TemplatedItems.GetGlobalIndexOfGroup(newContext);
            TemplatedItemsList <ItemsView <Cell>, Cell> group = lv.TemplatedItems.GetGroup(groupIndex);

            return(group);
        }
Пример #5
0
        internal static NSIndexPath GetIndexPath(this Cell self)
        {
            if (self == null)
            {
                throw new ArgumentNullException("self");
            }
            if (self.Parent is ListView)
            {
                int num   = 0;
                var group = TemplatedItemsList <ItemsView <Cell>, Cell> .GetGroup(self);

                if (group != null)
                {
                    num = TemplatedItemsList <ItemsView <Cell>, Cell> .GetIndex(group.HeaderContent);
                }

                return(NSIndexPath.FromItemSection((nint)num, (nint)0));
                //return NSIndexPath.FromRowSection ((nint)TemplatedItemsList<ItemsView<Cell>, Cell>.GetIndex (self), (nint)num);
            }
            if (!(self.Parent is TableView))
            {
                throw new NotSupportedException("Unknown cell parent type");
            }

            Tuple <int, int> path = TableView.TableSectionModel.GetPath(self);

            return(NSIndexPath.FromItemSection((nint)path.Item2, (nint)path.Item1));
        }
Пример #6
0
        protected MultiPage()
        {
            _templatedItems = new TemplatedItemsList <MultiPage <T>, T>(this, ItemsSourceProperty, ItemTemplateProperty);
            _templatedItems.CollectionChanged += OnTemplatedItemsChanged;

            _children = new ElementCollection <T>(InternalChildren);
            InternalChildren.CollectionChanged += OnChildrenChanged;
        }
Пример #7
0
        static Cell RealizeGroupedHeaderTemplate(TemplatedItemsList <ItemsView <Cell>, Cell> templatedItems,
                                                 ElementTemplate template, object context)
        {
            var index = templatedItems.GetGlobalIndexOfGroup(context);

            if (index > -1)
            {
                return(templatedItems[index]);
            }

            return(template.CreateContent() as Cell);
        }
Пример #8
0
        void SetCell(object newContext)
        {
            var cell = newContext as Cell;

            if (ReferenceEquals(Cell?.BindingContext, newContext))
            {
                return;
            }

            // If there is a ListView, load the Cell content from the ItemTemplate.
            // Otherwise, the given Cell is already a templated Cell from a TableView.
            ListView lv = _listView.Value;

            if (lv != null)
            {
                bool         isGroupHeader = IsGroupHeader;
                DataTemplate template      = isGroupHeader ? lv.GroupHeaderTemplate : lv.ItemTemplate;

                if (template is DataTemplateSelector)
                {
                    template = ((DataTemplateSelector)template).SelectTemplate(newContext, lv);
                }

                if (template != null)
                {
                    cell = template.CreateContent() as Cell;
                    cell.BindingContext = newContext;
                }
                else
                {
                    string textContent = newContext.ToString();

                    if (isGroupHeader)
                    {
                        TemplatedItemsList <ItemsView <Cell>, Cell> group = GetGroup(newContext, lv);
                        textContent = GetDisplayTextFromGroup(lv, group);
                    }

                    cell = lv.CreateDefaultCell(textContent);
                }

                // A TableView cell should already have its parent,
                // but we need to set the parent for a ListView cell.
                cell.Parent = lv;

                // This provides the Group Header styling (e.g., larger font, etc.) when the
                // template is loaded later.
                TemplatedItemsList <ItemsView <Cell>, Cell> .SetIsGroupHeader(cell, isGroupHeader);
            }

            Cell = cell;
        }
Пример #9
0
        public virtual System.Windows.DataTemplate GetTemplate(Cell cell)
        {
            if (cell.RealParent is ListView)
            {
                if (TemplatedItemsList <ItemsView <Cell>, Cell> .GetIsGroupHeader(cell))
                {
                    return((System.Windows.DataTemplate)System.Windows.Application.Current.Resources["ListViewHeaderTextCell"]);
                }

                return((System.Windows.DataTemplate)System.Windows.Application.Current.Resources["ListViewTextCell"]);
            }

            return((System.Windows.DataTemplate)System.Windows.Application.Current.Resources["TextCell"]);
        }
Пример #10
0
            /*
             * public override nint NumberOfSections (NSTableView tableView)
             * {
             *      if (this.list.IsGroupingEnabled)
             *              return (nint)this.list.TemplatedItems.Count;
             *      return (nint)1;
             * }
             *
             * public override nint RowsInSection (NSTableView tableview, nint section)
             * {
             *      int num;
             *      if (this.Counts.TryGetValue ((int)section, out num))
             *      {
             *              this.Counts.Remove ((int)section);
             *              return (nint)num;
             *      }
             *      if (this.list.IsGroupingEnabled)
             *              return (nint)((ICollection)((IList)this.list.TemplatedItems) [(int)section]).Count;
             *      return (nint)this.list.TemplatedItems.Count;
             * }
             */

            public override NSCell GetCell(NSTableView tableView, NSTableColumn tableColumn, nint row)
            {
                NSTableCellView cell1;
                NSTableViewCell tableViewCell;
                NSCell          cell;
                nint            section = 0;

                switch (this.list.CachingStrategy)
                {
                case ListViewCachingStrategy.RetainElement:
                    Cell cellForPath1 = this.GetCellFor(section, row);
                    cell1 = CellTableViewCell.GetNativeCell(tableView, cellForPath1, false);
                    break;

                case ListViewCachingStrategy.RecycleElement:

                    cell1 = null;                     // tableView.DequeueReusableCell ("ContextActionsCell");
                    if (cell1 == null)
                    {
                        Cell cellForPath2 = this.GetCellFor(section, row);
                        cell1 = CellTableViewCell.GetNativeCell(tableView, cellForPath2, true);
                        break;
                    }
                    TemplatedItemsList <ItemsView <Cell>, Cell> group = this.list.TemplatedItems.GetGroup((int)section);
                    Cell cell2 = (Cell)((INativeElementView)cell1).Element;
                    cell2.SendDisappearing();
                    Cell content = cell2;

                    group.UpdateContent(content, (int)row);
                    cell2.SendAppearing();
                    break;

                default:
                    throw new NotSupportedException();
                }
                // TODO: Figure this out
                //NSColor color = tableView.IndexPathForSelectedRow == null ||
                //	!tableView.IndexPathForSelectedRow.Equals (indexPath) ? this.DefaultBackgroundColor : NSColor.Clear;
                NSColor color = NSColor.Clear;

                ListViewRenderer.ListViewDataSource.SetCellBackgroundColor(cell1, color);

                // TODO: WT.? damit. NSCell, NSTableViewCell, NSTableCellView.  Soo confusing
                //return cell1;
                return(null);
            }
Пример #11
0
        void UpdateMainText()
        {
            var cell = (TextCell)Cell;

            View.MainText = cell.Text;

            if (!TemplatedItemsList <ItemsView <Cell>, Cell> .GetIsGroupHeader(cell))
            {
                View.SetDefaultMainTextColor(Color.Accent);
            }
            else
            {
                View.SetDefaultMainTextColor(Color.Default);
            }

            View.SetMainTextColor(cell.TextColor);
        }
Пример #12
0
 protected void UpdateBackground(NSTableCellView tableViewCell, Cell cell)
 {
     if (TemplatedItemsList <ItemsView <Cell>, Cell> .GetIsGroupHeader((BindableObject)cell))
     {
         var color = NSColor.FromDeviceRgba((nfloat)0.9686275f, (nfloat)0.9686275f, (nfloat)0.9686275f, (nfloat)1);
         tableViewCell.SetBackgroundColor(color);
     }
     else
     {
         NSColor       uiColor       = NSColor.White;
         VisualElement visualElement = cell.Parent as VisualElement;
         if (visualElement != null)
         {
             uiColor = visualElement.BackgroundColor == Color.Default ? uiColor : ColorExtensions.ToUIColor(visualElement.BackgroundColor);
         }
         tableViewCell.SetBackgroundColor(uiColor);
     }
 }
Пример #13
0
        static string GetDisplayTextFromGroup(ListView lv, TemplatedItemsList <ItemsView <Cell>, Cell> group)
        {
            string displayBinding = null;

            if (lv.GroupDisplayBinding != null)
            {
                displayBinding = group.Name;
            }

            if (lv.GroupShortNameBinding != null)
            {
                displayBinding = group.ShortName;
            }

            // TODO: what if they set both? should it default to the ShortName, like it will here?
            // ShortNames binding did not appear to be functional before.
            return(displayBinding);
        }
Пример #14
0
 /// <summary>
 /// This method is called whenever something changes in list view data model.
 /// Method will be invoked for grouping mode, but some action can be also handled
 /// by OnCollectionChanged handler.
 /// </summary>
 /// <param name="sender">TemplatedItemsList<ItemsView<Cell>, Cell>.</param>
 /// <param name="e">NotifyCollectionChangedEventArgs.</param>
 void OnGroupedCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 {
     if (e.Action == NotifyCollectionChangedAction.Add)
     {
         TemplatedItemsList <ItemsView <Cell>, Cell> itemsGroup = sender as TemplatedItemsList <ItemsView <Cell>, Cell>;
         Cell before = null;
         if (e.NewStartingIndex + e.NewItems.Count < itemsGroup.Count)
         {
             before = itemsGroup[e.NewStartingIndex + e.NewItems.Count];
         }
         Control.AddItemsToGroup(itemsGroup, e.NewItems, before);
     }
     else if (e.Action == NotifyCollectionChangedAction.Remove)
     {
         Control.Remove(e.OldItems);
     }
     else if (e.Action == NotifyCollectionChangedAction.Reset)
     {
         Control.ResetGroup(sender as TemplatedItemsList <ItemsView <Cell>, Cell>);
     }
 }
Пример #15
0
        public void GetGroup()
        {
            var items = new ObservableCollection <ObservableCollection <string> > {
                new ObservableCollection <string> {
                    "foo", "faz"
                },
                new ObservableCollection <string> {
                    "bar", "baz"
                }
            };

            bindable.ItemsSource           = items;
            bindable.GroupShortNameBinding = new Binding(".");
            bindable.IsGroupingEnabled     = true;

            var til  = bindable.TemplatedItems.GetGroup(1);
            var item = til[1];

            var group = TemplatedItemsList <ItemsView <BindableObject>, BindableObject> .GetGroup(item);

            Assert.That(group, Is.SameAs(til));
        }
Пример #16
0
        protected void UpdateBackground(UITableViewCell tableViewCell, Cell cell)
        {
            if (TemplatedItemsList <ItemsView <Cell>, Cell> .GetIsGroupHeader(cell))
            {
                if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0))
                {
                    tableViewCell.BackgroundColor = new UIColor(247f / 255f, 247f / 255f, 247f / 255f, 1);
                }
            }
            else
            {
                // Must be set to a solid color or blending issues will occur
                var bgColor = UIColor.White;

                var element = cell.RealParent as VisualElement;
                if (element != null)
                {
                    bgColor = element.BackgroundColor == Color.Default ? bgColor : element.BackgroundColor.ToUIColor();
                }

                tableViewCell.BackgroundColor = bgColor;
            }
        }
Пример #17
0
        void OnScrollToRequested(object sender, ScrollToRequestedEventArgs e)
        {
            if (!_isAttached)
            {
                _pendingScrollTo = e;
                return;
            }

            Cell cell;
            int  position;

            if (Element.IsGroupingEnabled)
            {
                var results = Element.TemplatedItems.GetGroupAndIndexOfItem(e.Group, e.Item);
                if (results.Item1 == -1 || results.Item2 == -1)
                {
                    return;
                }

                TemplatedItemsList <ItemsView <Cell>, Cell> group = Element.TemplatedItems.GetGroup(results.Item1);
                cell = group[results.Item2];

                position = Element.TemplatedItems.GetGlobalIndexForGroup(group) + results.Item2 + 1;
            }
            else
            {
                position = Element.TemplatedItems.GetGlobalIndexOfItem(e.Item);
                cell     = Element.TemplatedItems[position];
            }

            //Android offsets position of cells when using header
            int realPositionWithHeader = position + 1;

            if (e.Position == ScrollToPosition.MakeVisible)
            {
                if (e.ShouldAnimate)
                {
                    Control.SmoothScrollToPosition(realPositionWithHeader);
                }
                else
                {
                    Control.SetSelection(realPositionWithHeader);
                }
                return;
            }

            int height     = Control.Height;
            var cellHeight = (int)cell.RenderHeight;

            if (cellHeight == -1)
            {
                int first = Control.FirstVisiblePosition;
                if (first <= position && position <= Control.LastVisiblePosition)
                {
                    cellHeight = Control.GetChildAt(position - first).Height;
                }
                else
                {
                    AView view = _adapter.GetView(position, null, null);
                    view.Measure(MeasureSpecFactory.MakeMeasureSpec(Control.Width, MeasureSpecMode.AtMost), MeasureSpecFactory.MakeMeasureSpec(0, MeasureSpecMode.Unspecified));
                    cellHeight = view.MeasuredHeight;
                }
            }

            var y = 0;

            if (e.Position == ScrollToPosition.Center)
            {
                y = height / 2 - cellHeight / 2;
            }
            else if (e.Position == ScrollToPosition.End)
            {
                y = height - cellHeight;
            }

            if (e.ShouldAnimate)
            {
                Control.SmoothScrollToPositionFromTop(realPositionWithHeader, y);
            }
            else
            {
                Control.SetSelectionFromTop(realPositionWithHeader, y);
            }
        }
Пример #18
0
 public static bool GetIsGroupHeader <TView, TItem>(this TItem cell) where TView : BindableObject, ITemplatedItemsView <TItem> where TItem : BindableObject
 {
     return(TemplatedItemsList <TView, TItem> .GetIsGroupHeader(cell));
 }
Пример #19
0
 public static ITemplatedItemsList <TItem> GetGroup <TView, TItem>(this TItem cell) where TView : BindableObject, ITemplatedItemsView <TItem> where TItem : BindableObject
 {
     return(TemplatedItemsList <TView, TItem> .GetGroup(cell));
 }
Пример #20
0
 public static int GetIndex <TView, TItem>(this TItem cell) where TView : BindableObject, ITemplatedItemsView <TItem> where TItem : BindableObject
 {
     return(TemplatedItemsList <TView, TItem> .GetIndex(cell));
 }
Пример #21
0
        public static TItem GetGroupHeaderContent <TView, TItem>(this TItem cell) where TView : BindableObject, ITemplatedItemsView <TItem> where TItem : BindableObject
        {
            var group = TemplatedItemsList <TView, TItem> .GetGroup(cell);

            return(group.HeaderContent);
        }
Пример #22
0
 public static void SetIsGroupHeader <TView, TItem>(this TItem cell, bool value) where TView : BindableObject, ITemplatedItemsView <TItem> where TItem : BindableObject
 {
     TemplatedItemsList <TView, TItem> .SetIsGroupHeader(cell, value);
 }
 public ItemsTemplate()
 {
     this.TemplatedItems = new TemplatedItemsList <ItemsTemplate, Core.Element>(this);
     this.TemplatedItems.CollectionChanged += TemplatedItems_CollectionChanged;
 }
Пример #24
0
 /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/CellExtensions.xml" path="//Member[@MemberName='GetGroup']/Docs" />
 public static ITemplatedItemsList <TItem> GetGroup <TView, [DynamicallyAccessedMembers(BindableProperty.DeclaringTypeMembers)] TItem>(this TItem cell) where TView : BindableObject, ITemplatedItemsView <TItem> where TItem : BindableObject
 {
     return(TemplatedItemsList <TView, TItem> .GetGroup(cell));
 }
Пример #25
0
        public override AView GetView(int position, AView convertView, ViewGroup parent)
        {
            Cell cell = null;

            Performance.Start();

            ListViewCachingStrategy cachingStrategy = _listView.CachingStrategy;
            var nextCellIsHeader = false;

            if (cachingStrategy == ListViewCachingStrategy.RetainElement || convertView == null)
            {
                if (_listView.IsGroupingEnabled)
                {
                    List <Cell> cells = GetCellsFromPosition(position, 2);
                    if (cells.Count > 0)
                    {
                        cell = cells[0];
                    }

                    if (cells.Count == 2)
                    {
                        nextCellIsHeader = TemplatedItemsList <ItemsView <Cell>, Cell> .GetIsGroupHeader(cells[1]);
                    }
                }

                if (cell == null)
                {
                    cell = GetCellForPosition(position);
                    if (cell == null)
                    {
                        return(new AView(_context));
                    }
                }
            }

            var makeBline = true;
            var layout    = convertView as ConditionalFocusLayout;

            if (layout != null)
            {
                makeBline   = false;
                convertView = layout.GetChildAt(0);
            }
            else
            {
                layout = new ConditionalFocusLayout(_context)
                {
                    Orientation = Orientation.Vertical
                }
            };

            if (cachingStrategy == ListViewCachingStrategy.RecycleElement && convertView != null)
            {
                var boxedCell = (INativeElementView)convertView;
                if (boxedCell == null)
                {
                    throw new InvalidOperationException($"View for cell must implement {nameof(INativeElementView)} to enable recycling.");
                }
                cell = (Cell)boxedCell.Element;

                if (ActionModeContext == cell)
                {
                    // This appears to never happen, the theory is android keeps all views alive that are currently selected for long-press (preventing them from being recycled).
                    // This is convenient since we wont have to worry about the user scrolling the cell offscreen and us losing our context actions.
                    ActionModeContext = null;
                    ContextView       = null;
                }
                // We are going to re-set the Platform here because in some cases (headers mostly) its possible this is unset and
                // when the binding context gets updated the measure passes will all fail. By applying this hear the Update call
                // further down will result in correct layouts.
                cell.Platform = _listView.Platform;

                cell.SendDisappearing();

                int row   = position;
                var group = 0;
                if (_listView.IsGroupingEnabled)
                {
                    group = _listView.TemplatedItems.GetGroupIndexFromGlobal(position, out row);
                }

                TemplatedItemsList <ItemsView <Cell>, Cell> templatedList = _listView.TemplatedItems.GetGroup(group);

                if (_listView.IsGroupingEnabled)
                {
                    if (row == 0)
                    {
                        templatedList.UpdateHeader(cell, group);
                    }
                    else
                    {
                        templatedList.UpdateContent(cell, row - 1);
                    }
                }
                else
                {
                    templatedList.UpdateContent(cell, row);
                }

                cell.SendAppearing();

                if (cell.BindingContext == ActionModeObject)
                {
                    ActionModeContext = cell;
                    ContextView       = layout;
                }

                if (ReferenceEquals(_listView.SelectedItem, cell.BindingContext))
                {
                    Select(_listView.IsGroupingEnabled ? row - 1 : row, layout);
                }
                else if (cell.BindingContext == ActionModeObject)
                {
                    SetSelectedBackground(layout, true);
                }
                else
                {
                    UnsetSelectedBackground(layout);
                }

                Performance.Stop();
                return(layout);
            }

            AView view = CellFactory.GetCell(cell, convertView, parent, _context, _listView);

            Performance.Start("AddView");

            if (!makeBline)
            {
                if (convertView != view)
                {
                    layout.RemoveViewAt(0);
                    layout.AddView(view, 0);
                }
            }
            else
            {
                layout.AddView(view, 0);
            }

            Performance.Stop("AddView");

            AView bline;

            if (makeBline)
            {
                bline = new AView(_context)
                {
                    LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, 1)
                };

                layout.AddView(bline);
            }
            else
            {
                bline = layout.GetChildAt(1);
            }

            bool isHeader = TemplatedItemsList <ItemsView <Cell>, Cell> .GetIsGroupHeader(cell);

            Color separatorColor = _listView.SeparatorColor;

            if (nextCellIsHeader || _listView.SeparatorVisibility == SeparatorVisibility.None)
            {
                bline.SetBackgroundColor(global::Android.Graphics.Color.Transparent);
            }
            else if (isHeader || !separatorColor.IsDefault)
            {
                bline.SetBackgroundColor(separatorColor.ToAndroid(Color.Accent));
            }
            else
            {
                if (s_dividerHorizontalDarkId == int.MinValue)
                {
                    using (var value = new TypedValue())
                    {
                        int id = global::Android.Resource.Drawable.DividerHorizontalDark;
                        if (_context.Theme.ResolveAttribute(global::Android.Resource.Attribute.ListDivider, value, true))
                        {
                            id = value.ResourceId;
                        }
                        else if (_context.Theme.ResolveAttribute(global::Android.Resource.Attribute.Divider, value, true))
                        {
                            id = value.ResourceId;
                        }

                        s_dividerHorizontalDarkId = id;
                    }
                }

                bline.SetBackgroundResource(s_dividerHorizontalDarkId);
            }

            if ((bool)cell.GetValue(IsSelectedProperty))
            {
                Select(position, layout);
            }
            else
            {
                UnsetSelectedBackground(layout);
            }

            layout.ApplyTouchListenersToSpecialCells(cell);

            Performance.Stop();

            return(layout);
        }
Пример #26
0
 /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/CellExtensions.xml" path="//Member[@MemberName='SetIsGroupHeader']/Docs" />
 public static void SetIsGroupHeader <TView, [DynamicallyAccessedMembers(BindableProperty.DeclaringTypeMembers)] TItem>(this TItem cell, bool value) where TView : BindableObject, ITemplatedItemsView <TItem> where TItem : BindableObject
 {
     TemplatedItemsList <TView, TItem> .SetIsGroupHeader(cell, value);
 }
Пример #27
0
        void OnScrollToRequested(object sender, ScrollToRequestedEventArgs e)
        {
            if (_animatable == null && e.ShouldAnimate)
            {
                _animatable = new Animatable();
            }

            if (_viewport == null)
            {
                // Making sure we're actually loaded
                if (VisualTreeHelper.GetChildrenCount(_listBox) == 0)
                {
                    RoutedEventHandler handler = null;
                    handler = (o, args) =>
                    {
                        Control.Loaded -= handler;
                        OnScrollToRequested(sender, e);
                    };
                    Control.Loaded += handler;

                    return;
                }
                _viewport = (ViewportControl)VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(_listBox, 0), 0), 0);
                if (_viewport.Viewport.Bottom == 0)
                {
                    EventHandler <ViewportChangedEventArgs> viewportChanged = null;
                    viewportChanged = (o, args) =>
                    {
                        if (_viewport.Viewport.Bottom == 0)
                        {
                            return;
                        }

                        _viewport.ViewportChanged -= viewportChanged;
                        OnScrollToRequested(sender, e);
                    };
                    _viewport.ViewportChanged += viewportChanged;
                    return;
                }
            }

            double y                  = 0;
            double targetHeight       = 0;
            double targetHeaderHeight = 0;

            var templateReusables = new Dictionary <System.Windows.DataTemplate, FrameworkElement>();

            var found = false;

            if (Element.IsGroupingEnabled)
            {
                for (var g = 0; g < Element.TemplatedItems.Count; g++)
                {
                    if (found)
                    {
                        break;
                    }

                    TemplatedItemsList <ItemsView <Cell>, Cell> til = Element.TemplatedItems.GetGroup(g);

                    double headerHeight = GetHeight(templateReusables, Control.GroupHeaderTemplate, til);
                    y += headerHeight;

                    for (var i = 0; i < til.Count; i++)
                    {
                        Cell cell = til[i];

                        double contentHeight = GetHeight(templateReusables, Control.ItemTemplate, cell);

                        if ((ReferenceEquals(til.BindingContext, e.Group) || e.Group == null) && ReferenceEquals(cell.BindingContext, e.Item))
                        {
                            targetHeaderHeight = headerHeight;
                            targetHeight       = contentHeight;
                            found = true;
                            break;
                        }

                        y += contentHeight;
                    }
                }
            }
            else
            {
                for (var i = 0; i < Element.TemplatedItems.Count; i++)
                {
                    Cell cell = Element.TemplatedItems[i];

                    double height = GetHeight(templateReusables, Control.ItemTemplate, cell);

                    if (ReferenceEquals(cell.BindingContext, e.Item))
                    {
                        found        = true;
                        targetHeight = height;
                        break;
                    }

                    y += height;
                }
            }

            if (!found)
            {
                return;
            }

            ScrollToPosition position = e.Position;

            if (position == ScrollToPosition.MakeVisible)
            {
                if (y >= _viewport.Viewport.Top && y <= _viewport.Viewport.Bottom)
                {
                    return;
                }
                if (y > _viewport.Viewport.Bottom)
                {
                    position = ScrollToPosition.End;
                }
                else
                {
                    position = ScrollToPosition.Start;
                }
            }

            if (position == ScrollToPosition.Start && Element.IsGroupingEnabled)
            {
                y = y - targetHeaderHeight;
            }
            else if (position == ScrollToPosition.Center)
            {
                y = y - (_viewport.ActualHeight / 2 + targetHeight / 2);
            }
            else if (position == ScrollToPosition.End)
            {
                y = y - _viewport.ActualHeight + targetHeight;
            }

            double startY   = _viewport.Viewport.Y;
            double distance = y - startY;

            if (e.ShouldAnimate)
            {
                var animation = new Animation(v => { _viewport.SetViewportOrigin(new System.Windows.Point(0, startY + distance * v)); });

                animation.Commit(_animatable, "ScrollTo", length: 500, easing: Easing.CubicInOut);
            }
            else
            {
                _viewport.SetViewportOrigin(new System.Windows.Point(0, y));
            }
        }
Пример #28
0
        // TODO: We can optimize this by storing the last position, group index and global index
        // and increment/decrement from that starting place.
        List <Cell> GetCellsFromPosition(int position, int take)
        {
            var cells = new List <Cell>(take);

            if (position < 0)
            {
                return(cells);
            }

            if (!_listView.IsGroupingEnabled)
            {
                for (var x = 0; x < take; x++)
                {
                    if (position + x >= _listView.TemplatedItems.Count)
                    {
                        return(cells);
                    }

                    cells.Add(_listView.TemplatedItems[x + position]);
                }

                return(cells);
            }

            var i      = 0;
            var global = 0;

            for (; i < _listView.TemplatedItems.Count; i++)
            {
                TemplatedItemsList <ItemsView <Cell>, Cell> group = _listView.TemplatedItems.GetGroup(i);

                if (global == position || cells.Count > 0)
                {
                    if (_listView.CachingStrategy == ListViewCachingStrategy.RecycleElement)
                    {
                        var groupContent = _listView.TemplatedItems.GroupHeaderTemplate.CreateContent(group.ItemsSource, _listView) as Cell;
                        if (groupContent != null)
                        {
                            groupContent.BindingContext = group.ItemsSource;
                            cells.Add(groupContent);
                        }
                    }
                    else
                    {
                        cells.Add(group.HeaderContent);
                    }

                    if (cells.Count == take)
                    {
                        return(cells);
                    }
                }

                global++;

                if (global + group.Count < position)
                {
                    global += group.Count;
                    continue;
                }

                for (var g = 0; g < group.Count; g++)
                {
                    if (global == position || cells.Count > 0)
                    {
                        cells.Add(group[g]);
                        if (cells.Count == take)
                        {
                            return(cells);
                        }
                    }

                    global++;
                }
            }

            return(cells);
        }
Пример #29
0
        /// <include file="../../../docs/Microsoft.Maui.Controls.Internals/CellExtensions.xml" path="//Member[@MemberName='GetGroupHeaderContent']/Docs" />
        public static TItem GetGroupHeaderContent <TView, [DynamicallyAccessedMembers(BindableProperty.DeclaringTypeMembers)] TItem>(this TItem cell) where TView : BindableObject, ITemplatedItemsView <TItem> where TItem : BindableObject
        {
            var group = TemplatedItemsList <TView, TItem> .GetGroup(cell);

            return(group.HeaderContent);
        }
Пример #30
0
 int GetIndex(BindableObject item)
 {
     return(TemplatedItemsList <ItemsView <BindableObject>, BindableObject> .GetIndex(item));
 }
Пример #31
0
		static string GetDisplayTextFromGroup(ListView lv, TemplatedItemsList<ItemsView<Cell>, Cell> group)
		{
			string displayBinding = null;

			if (lv.GroupDisplayBinding != null)
				displayBinding = group.Name;

			if (lv.GroupShortNameBinding != null)
				displayBinding = group.ShortName;

			// TODO: what if they set both? should it default to the ShortName, like it will here?
			// ShortNames binding did not appear to be functional before.
			return displayBinding;
		}