/// <summary> /// Get control inside the specified layout template. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="mode">The layout mode in which the control is defined</param> /// <param name="name">The 'x:Name' of the control</param> /// <returns></returns> /// <remarks>The caller must ensure the control is loaded. This is best done from <see cref="FrameworkElement.Loaded"/> event.</remarks> public T GetSampleChild <T>(Design mode, string name) where T : FrameworkElement { var presenter = (ContentPresenter)GetTemplateChild($"{mode}ContentPresenter"); return(VisualTreeHelperEx.GetFirstDescendant <T>(presenter, x => x.Name == name)); }
private void AddNavigationItems(MUXC.NavigationView nv) { var categories = Assembly.GetExecutingAssembly().DefinedTypes .Where(x => x.Namespace?.StartsWith("Uno.Themes.Samples") == true) .Select(x => new { TypeInfo = x, SamplePageAttribute = x.GetCustomAttribute <SamplePageAttribute>() }) .Where(x => x.SamplePageAttribute != null) .Select(x => new Sample(x.SamplePageAttribute, x.TypeInfo.AsType())) .OrderByDescending(x => x.SortOrder.HasValue) .ThenBy(x => x.SortOrder) .ThenBy(x => x.Title) .GroupBy(x => x.Category); foreach (var category in categories.OrderBy(x => x.Key)) { var tier = 1; var parentItem = default(MUXC.NavigationViewItem); if (category.Key != SampleCategory.None) { parentItem = new MUXC.NavigationViewItem { Content = category.Key.GetDescription() ?? category.Key.ToString(), SelectsOnInvoked = false, Style = (Style)Resources[$"T{tier++}NavigationViewItemStyle"] }.Apply(NavViewItemVisualStateFix); AutomationProperties.SetAutomationId(parentItem, "Section_" + parentItem.Content); nv.MenuItems.Add(parentItem); } foreach (var sample in category) { var item = new MUXC.NavigationViewItem { Content = sample.Title, DataContext = sample, Style = (Style)Resources[$"T{tier}NavigationViewItemStyle"] }.Apply(NavViewItemVisualStateFix); AutomationProperties.SetAutomationId(item, "Section_" + item.Content); (parentItem?.MenuItems ?? nv.MenuItems).Add(item); } } void NavViewItemVisualStateFix(MUXC.NavigationViewItem nvi) { // gallery#107: on uwp and uno, deselecting a NVI by selecting another NVI will leave the former in the "Selected" state // to workaround this, we force reset the visual state when IsSelected becomes false nvi.RegisterPropertyChangedCallback(MUXC.NavigationViewItemBase.IsSelectedProperty, (s, e) => { if (!nvi.IsSelected) { // depending on the DisplayMode, a NVIP may or may not be used. var nvip = VisualTreeHelperEx.GetFirstDescendant <MUXCP.NavigationViewItemPresenter>(nvi, x => x.Name == "NavigationViewItemPresenter"); VisualStateManager.GoToState((Control)nvip ?? nvi, "Normal", true); } }); } }
private double GetRelativeOffset() { #if NETFX_CORE // On UWP we can count on finding a ScrollContentPresenter. var scp = VisualTreeHelperEx.GetFirstDescendant <ScrollContentPresenter>(_scrollViewer); var content = scp?.Content as FrameworkElement; var transform = _scrollingTabs.TransformToVisual(content); return(transform.TransformPoint(new Point(0, 0)).Y - _scrollViewer.VerticalOffset); #elif __IOS__ var transform = _scrollingTabs.TransformToVisual(_scrollViewer); return(transform.TransformPoint(new Point(0, 0)).Y); #else var transform = _scrollingTabs.TransformToVisual(this); return(transform.TransformPoint(new Point(0, 0)).Y - _top.ActualHeight); #endif }
private static void InstallIncrementalLoadingWorkaround(object sender, RoutedEventArgs _) { var lv = (ListView)sender; var sv = VisualTreeHelperEx.GetFirstDescendant <ScrollViewer>(lv); sv.ViewChanged += async(s, e) => { if (lv.ItemsSource is not ISupportIncrementalLoading source) { return; } if (lv.Items.Count > 0 && !source.HasMoreItems) { return; } if (GetIsIncrementallyLoading(lv)) { return; } // note: for simplicity, we assume the ItemsPanel is stacked vertically // try to load more when there is less than half a page; // sv.VerticalOffset only represents the top of rendered area, // we need another sv.ViewportHeight (or 1.0 after division) to get to the bottom if (((sv.ExtentHeight - sv.VerticalOffset) / sv.ViewportHeight) - 1.0 <= 0.5) { try { SetIsIncrementallyLoading(lv, true); await source.LoadMoreItemsAsync(1); } catch (Exception ex) { typeof(ListViewExtensions).Log().Error("failed to load more items: ", ex); } finally { SetIsIncrementallyLoading(lv, false); } } }; }