Silverlight TabControl-поиск и выбор TabItem из данного элемента управления в TabItem
Я создаю приложение LOB, которое имеет основной раздел и TabControl с различными TabItems в нем. При нажатии save идея заключается в том, что любые поля по ошибке выделяются, а первое поле по ошибке получает фокус.
Если первое и единственное поле ошибки находится на невыбранной вкладке, вкладка должна быть выбрана, а поле ошибки должно быть выделено и иметь фокус. Но я не могу заставить это работать.
кажется, что происходит то, что Невыбранная вкладка не находится в визуальном дереве, поэтому вы не можете вернуться к владеющему TabItem и сделать его выбранным TabItem в TabControl.
есть ли у кого-нибудь идея о том, как это можно сделатьдостичь?
5 ответов
чтобы загрузить TabItem:
tabControl.SelectedItem = tabItemOfInterest;
tabControl.UpdateLayout();
это заставляет tabItemOfInterest загружать вместе со всеми содержащимися элементами управления в TabItem.
только строка ниже не загружает tabItemOfInterest:
tabControl.SelectedItem = tabItemOfInterest;
Я, однако, был бы очень заинтересован в подходе, который Дэвид принял, чтобы добраться до ошибочного контроля.
Как я решил это (спросив ведущего архитектора)...
создайте интерфейс ITabActivator с одним методом активации.
создайте класс, производный от Grid и ITabActivator, называемый TabPageActivator. Конструктор которого принимает TabITem и TabControl.
вместо добавления простой сетки в TabItem.Содержимое добавьте TabPageActivator.
измените родительское обнаружение для использования...
DependencyObject parent = _Контроль.Родитель;
...вместо использования VisualTreeHelper.
поэтому при навигации по тесту иерархии для...
if (родитель-TabActivator ) (родитель как ITabActivator).Активировать ()
... поэтому при активации вызывается
m_TabControl.SelectedItem = m_TabItem; / / из параметров конструктора.
...и не забывайте, что у вас могут быть вложенные вкладки, поэтому вам нужно продолжать подниматься по иерархии.
Я использую TabControls для навигации на одном из моих сайтов (YinYangMoney) и построил несколько методов расширения, которые помогают мне выбрать вкладки, используя имена тегов. Вот фрагменты, которые должны работать для вас.
класс расширениями:
using System;
using System.Linq;
using System.Windows.Controls;
namespace MyApplication
{
internal static class Extensions
{
// Extension for TabControl
internal static void SelectTab(this TabControl tabControl, this TabItem tabItem)
{
if (tabControl == null || tabItem == null)
return null;
SelectTab(tabControl, tabItem.Tag);
}
// Extension for TabControl
internal static void SelectTab(this TabControl tabControl, string tabTagName)
{
if (tabControl == null)
return null;
// Find the TabItem by its Tag name
TabItem mainTabItem = tabControl.FindByTag(tabTagName);
if (mainTabItem == null)
return;
// Check to see if the tab needs to be selected
if (tabControl.SelectedItem != mainTabItem)
tabControl.SelectedItem = mainTabItem;
}
// Extension for TabControl
internal static TabItem FindByTag(this TabControl tabControl, string tagFragment)
{
if (tabControl == null || tagFragment == null)
return null;
return tabControl.Items
.OfType<TabItem>()
.Where(item => item.Tag != null && item.Tag.ToString().StartsWithIgnoreCase(tagFragment))
.FirstOrDefault();
}
// Extension for string
internal static bool StartsWithIgnoreCase(this string source, string target)
{
return source.StartsWith(target, StringComparison.CurrentCultureIgnoreCase);
}
}
}
XAML для вашего TabControl и TabItems будет выглядеть примерно так:
<Controls:TabControl x:Name="x_TabControl">
<Controls:TabItem Header="Welcome" Tag="/Home/Welcome" x:Name="x_WelcomeTab" />
<Controls:TabItem Header="FAQ" Tag="/Home/FAQ" />
<Controls:TabItem Header="Contact Us" Tag="/Home/Contact_Us" />
<Controls:TabItem Header="Privacy Policy" Tag="/Home/Privacy_Policy" />
<Controls:TabItem Header="My Account" Tag="/Home/My_Account" />
</Controls:TabControl>
и вы можете выбрать приветствие TabItem как Итак:
x_TabControl.SelectTab("/Home/Welcome");
или
x_TabControl.SelectTab(x_WelcomeTab);
мое решение с использованием вложенного свойства TabItem. Создать класс TabItemExtender:
/// <summary>
/// TabItem Extender class with TabItem property
/// </summary>
public class TabItemExtender
{
#region property getters/setters
/// <summary>
/// TabItem attached dependency property
/// </summary>
public static readonly DependencyProperty TabItemProperty = DependencyProperty.RegisterAttached("TabItem", typeof(TabItem), typeof(TabItemExtender), null);
/// <summary>
/// TabItem Property getter
/// </summary>
public static TabItem GetNavigateUri(DependencyObject source)
{
return (TabItem)source.GetValue(TabItemExtender.TabItemProperty);
}
/// <summary>
/// TabItem Property setter
/// </summary>
public static void SetNavigateUri(DependencyObject target, TabItem value)
{
target.SetValue(TabItemExtender.TabItemProperty, value);
}
#endregion
}
далее сделайте это на TabControl загрузить событие:
private void ExtendedTabControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
foreach (object item in this.Items)
{
var tabItem = item as TabItem;
if (tabItem != null && tabItem.Content != null)
{
var element = (FrameworkElement)tabItem.Content;
element.SetValue(TabItemExtender.TabItemProperty, tabItem);
}
}
}
и это перед установкой фокуса:
var element = (UIElement)control;
while (element != null)
{
//Get TabItem
var tabItem = (TabItem)element.GetValue(TabItemExtender.TabItemProperty);
if (tabItem != null)
{
if (!tabItem.IsSelected && tabItem.IsEnabled)
{
tabItem.IsSelected = true;
((TabControl)tabItem.Parent).UpdateLayout();
}
break;
}
element = (UIElement)VisualTreeHelper.GetParent(element);
}
control.Focus();
Я знаю способ, но это некрасиво. Он включает в себя использование DispatcherTimer с интервалом в несколько миллисекунд. В Page_Loaded вы запустите таймер. Затем на каждом ТИКе он устанавливает IsSelected = true для одного из элементов вкладки. На следующем тике он выбирает следующий элемент вкладки и т. д. пока не будут выбраны все вкладки. Затем вам нужно будет снова выбрать первый элемент и убить таймер. Это заставит визуальные элементы в элементах вкладки загружаться.
Вам также придется покрыть TabControl с границей или что-то во время этой операции. В противном случае пользователь увидит, что все элементы вкладки быстро пролистываются.