Using FindChildren, it works for me.
var list = new List<ScrollViewer>();
FindChildren(list, sender);
list[0].ChangeView(0,null,null);
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
There are many tabs in a TabView Control in WinUI3 App. I made a function: pin a selected tab to top. After set it to the top (meaning the first tab ), I make it be selected. Everything is ok, but the first selected tab may be hidden if I had previously chosen to set the tabs at the end to the top. So how to scroll the tab area in code?
You can Implement browser-style keyboarding behavior using SelectedIndex
instead of calling the scrolling control function directly.
Setting the SelectedIndex property can change the selected tab, which is exactly what I did, but it does not make the header of the tab visible.
You may provide some code snippets about how to reproduce your issue.
OK, please check the following screenshot and code.
/// <summary>
/// Popup menu: Pin the selected tab to top
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MenuPin_Click(object sender, RoutedEventArgs e)
{
var curSelected = (TabViewFolders.SelectedItem as ViewFolder);
// Step1: Remove the current tab that triggered the popup menu from the binding collection
GlobalVariables.BindingFolders.Remove(curSelected);
// Step2: Insert the removed item as the first tab int the binding collection
GlobalVariables.BindingFolders.Insert(0, curSelected);
// Step3; Make the first tab to be selected.
// but the tabs' display area will not auto scroll to the selected one.
// So how to write code to scroll to the selected tab?
TabViewFolders.SelectedIndex = 0;
}
You can try the TabView.SelectedItem Property and UIElement.UpdateLayout. If they don't work, you can use ScrollViewer.ChangeView Method on the ScrollViewer which is in the TabView with the VisualTreeHelper Class. See TabView.xaml.
Using FindChildren, it works for me.
var list = new List<ScrollViewer>();
FindChildren(list, sender);
list[0].ChangeView(0,null,null);
OK, thanks! It works now with ScrollViewer.ChangeView method. But there is still a little bug showing below:
@C CB, could you please show a minimal, reproducible sample without private information?
OK. I paste a complete xaml & cs sample WinUI3 program showing below.
using Microsoft.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace WInUI3B_Packaged
{
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class TestWindowForTabView : Window
{
private int ITEM_COUNT = 10;
public TestWindowForTabView()
{
this.InitializeComponent();
this.AppWindow.Resize(new Windows.Graphics.SizeInt32(830, 600));
}
private void tabviewTest_Loaded(object sender, RoutedEventArgs e)
{
int intStart = (int)'A';
for (int i = 0; i < ITEM_COUNT; i++)
{
TabViewItem item = new TabViewItem();
char headerChar = (char)(intStart + i);
string headerText = headerChar.ToString().PadRight(3, headerChar);
item.Header = headerText;
item.MaxWidth = 100;
item.MinWidth = 100;
item.IsClosable = false;
item.Background = new SolidColorBrush(Colors.LightBlue);
tabviewTest.TabItems.Add(item);
}
}
private void btnTest_Click(object sender, RoutedEventArgs e)
{
int childCount = tabviewTest.TabItems.Count;
if (childCount < ITEM_COUNT) { return; }
txtResult.Text = "";
int targetIndex = 4;// Maybe you need to change the value for your Screen resolution
if (tabviewTest.SelectedIndex != targetIndex)
{
txtResult.Text = "Please select tab 'EEE' first.";
return;
}
TabViewItem targetItem = (TabViewItem)tabviewTest.TabItems[targetIndex];
tabviewTest.TabItems.RemoveAt(targetIndex);
tabviewTest.TabItems.Insert(0, targetItem);
tabviewTest.SelectedIndex = 0;
var list = FindChildren<ScrollViewer>(tabviewTest);
if (list != null && list.Count > 0)
{
list[0].ChangeView(0, null, null);
}
}
public static List<T> FindChildren<T>(DependencyObject parent) where T : DependencyObject
{
if (parent == null) return null;
List<T> retList = new List<T>();
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is T)
{
retList.Add((T)child);
}
else
{
retList.AddRange(FindChildren<T>(child));
}
}
return retList;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="WInUI3B_Packaged.TestWindowForTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WInUI3B_Packaged"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<StackPanel Orientation="Vertical">
<TabView x:Name="tabviewTest" Loaded="tabviewTest_Loaded" />
<Border Height="60" />
<StackPanel HorizontalAlignment="Center" Orientation="Vertical">
<TextBlock Text="1. Clike tab 'EEE' to select it." ></TextBlock>
<TextBlock Text="2. Clike the button 'Pin to top', you will see the bug UI." ></TextBlock>
<Button x:Name="btnTest" Click="btnTest_Click" Width="220" Background="LightGray">Pin to top</Button>
<TextBlock x:Name="txtResult" Text="" Foreground="Red" ></TextBlock>
</StackPanel>
</StackPanel>
</Grid>
</Window>
OK, the following is a complete WinUI3 window program code.
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="WInUI3B_Packaged.TestWindowForTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WInUI3B_Packaged"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<StackPanel Orientation="Vertical">
<TabView x:Name="tabviewTest" Loaded="tabviewTest_Loaded" />
<Border Height="60" />
<StackPanel HorizontalAlignment="Center" Orientation="Vertical">
<TextBlock Text="1. Clike tab 'EEE' to select it." ></TextBlock>
<TextBlock Text="2. Clike the button 'Pin to top', you will see the bug UI." ></TextBlock>
<Button x:Name="btnTest" Click="btnTest_Click" Width="220" Background="LightGray">Pin to top</Button>
<TextBlock x:Name="txtResult" Text="" Foreground="Red" ></TextBlock>
</StackPanel>
</StackPanel>
</Grid>
</Window>
using Microsoft.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace WInUI3B_Packaged
{
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class TestWindowForTabView : Window
{
private int ITEM_COUNT = 10;
public TestWindowForTabView()
{
this.InitializeComponent();
this.AppWindow.Resize(new Windows.Graphics.SizeInt32(830, 600));
}
private void tabviewTest_Loaded(object sender, RoutedEventArgs e)
{
int intStart = (int)'A';
for (int i = 0; i < ITEM_COUNT; i++)
{
TabViewItem item = new TabViewItem();
char headerChar = (char)(intStart + i);
string headerText = headerChar.ToString().PadRight(3, headerChar);
item.Header = headerText;
item.MaxWidth = 100;
item.MinWidth = 100;
item.IsClosable = false;
item.Background = new SolidColorBrush(Colors.LightBlue);
tabviewTest.TabItems.Add(item);
}
}
private void btnTest_Click(object sender, RoutedEventArgs e)
{
int childCount = tabviewTest.TabItems.Count;
if (childCount < ITEM_COUNT) { return; }
txtResult.Text = "";
int targetIndex = 4;// Maybe you need to change the value for your Screen resolution
if (tabviewTest.SelectedIndex != targetIndex)
{
txtResult.Text = "Please select tab 'EEE' first.";
return;
}
TabViewItem targetItem = (TabViewItem)tabviewTest.TabItems[targetIndex];
tabviewTest.TabItems.RemoveAt(targetIndex);
tabviewTest.TabItems.Insert(0, targetItem);
tabviewTest.SelectedIndex = 0;
var list = FindChildren<ScrollViewer>(tabviewTest);
if (list != null && list.Count > 0)
{
list[0].ChangeView(0, null, null);
}
}
public static List<T> FindChildren<T>(DependencyObject parent) where T : DependencyObject
{
if (parent == null) return null;
List<T> retList = new List<T>();
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is T)
{
retList.Add((T)child);
}
else
{
retList.AddRange(FindChildren<T>(child));
}
}
return retList;
}
}
}
@C CB, it works for me.
Hi, Maybe you didn't follow my steps to operate.
@C CB, do you mean this? Both LLL
and MMM
are tested.
OK. I change another description to show the bug, please check the below screenshots:
Maybe the website has a bug too, has my comment been submitted yet?
@C CB, it's due to your resizing. Add tabviewTest.UpdateLayout();
var list = FindChildren<ScrollViewer>(tabviewTest);
if (list != null && list.Count > 0)
{
list[0].ChangeView(0, null, null);
}
tabviewTest.UpdateLayout();
The bug still exists.
OK. You can report it at https://github.com/microsoft/microsoft-ui-xaml/issues.