Как программно изменить индекс и состояние элемента управления вкладкой (возможно, с помощью команд?) - PullRequest
1 голос
/ 05 декабря 2009

У меня есть WPF TabControl, который содержит число TabItem с дочерними UserControl с, вот так.

XAML:

<TabControl x:Name="tabsMain"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            Grid.Row="0" Grid.RowSpan="3" Background="lightgray">
    <TabItem Width="100" Header="Profile" FontSize="16">
        <InfoControl:InfoTab x:Name="myInfo" />
    </TabItem>
    <TabItem Width="120" x:Name="Summary" Header="Summary"  FontSize="16">
        <SummaryControl:SummaryTab/>
    </TabItem>
</TabControl>

В течение одного из UserControl с, скажем, InfoTab, у меня есть Button. При нажатии на Button я бы хотел изменить индекс TabControl на SummaryTab и выбрать переключатель на странице SummaryTab.

Моя проблема в том, что пользовательский элемент управления InfoTab не имеет доступа к MainUserControl, который содержит TabControl, показанный выше. Я понял, что kludge изменяет SelectedIndex из TabControl, но это очень уродливое решение, и я предпочел бы сделать что-то более чистое. Также я не могу в настоящее время изменить RadioButton на моем SummaryTab.

Мой текущий C # хак:

  Private void btnSummaryDetails_Click(object sender, RoutedEventArgs e)
  {
    TabControl tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "tabsMain");
    tabControl.SelectedIndex = 7;
  } 

Можно ли использовать команды или свойства зависимостей для выбора SummaryTab и моего желаемого RadioButton? Я все еще новичок в мире WPF и хотел бы узнать больше об этом. Заранее спасибо.

См. мой пост здесь для определения UIHelper, которое я использую в C # выше.

Ответы [ 3 ]

1 голос
/ 05 декабря 2009

Вероятно, вы можете использовать WPF перенаправленные события для решения вашей проблемы.Маршрутизируемые события используют визуальное дерево WPF для отправки событий до родительских элементов управления (всплывающее сообщение) или до дочерних элементов управления (туннелирование) без чрезмерной связи.Я попытался привести простой пример ниже, потому что я знаю, что перенаправленные события поначалу могут быть немного сложны для изучения, но это того стоит ...

В главном окне определите перенаправленное событие и добавьтеметод обработчика:

public partial class MainWindow : Window {

    public static RoutedEvent ClickedEvent = EventManager.RegisterRoutedEvent(
        "Clicked",
        RoutingStrategy.Bubble,
        typeof(RoutedEventHandler),
        typeof(MainWindow));

    public MainWindow() {
        InitializeComponent();

        this.AddHandler(MainWindow.ClickedEvent, new RoutedEventHandler(OnClickedEvent));
    }

    public void OnClickedEvent(object sender, RoutedEventArgs e) {
        // do your work here

    }
}

В обработчике щелчка по кнопке вызовите событие:

public partial class UserControl1 : UserControl {
    public UserControl1() {
        InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e) {

        // raise the event (gets bubbled up to the parent of the control)
        this.RaiseEvent(new RoutedEventArgs(MainWindow.ClickedEvent));

    }
}

Следующим шагом будет туннелирование другого события вниз по визуальному дереву и позволить другому пользователю управлятьпослушай это.

1 голос
/ 05 декабря 2009

Одна мысль приходит в голову, что не потребует слишком много изменений.

Сначала добавьте событие в ваш класс InfoTab:

public event EventHandler SummaryButtonClicked;

Затем обработайте это в основной форме, заменив объявление элемента управления на:

<InfoControl:InfoTab x:Name="myInfo" SummaryButtonClicked="summaryButtonClicked" />

И дайте имя вашему SummaryTab:

<SummaryControl:SummaryTab x:Name="summaryTab" />

Затем добавьте обработчик событий в основную форму:

void MainWindow_SummaryButtonClicked(object sender, EventArgs e)
{
    this.summaryTab.SelectRadioButton();
}

И добавьте метод в свой класс SummaryTab для выбора переключателя.

public void SelectRadioButton()
{
    // TODO: something like
    myRadioButton.IsChecked = true;
}
0 голосов
/ 11 декабря 2009

Я закончил тем, что добавил публичный метод, как Джереми предложил в своем посте. Простое, но эффективное решение. Спасибо, Джереми!

Другая ключевая реализация состояла в том, что для переключения tabcontrol по индексу я могу получить ссылку на основной пользовательский элемент управления и установить SelectedItem на сам TabItem, например:

  Private void btnSummaryDetails_Click(object sender, RoutedEventArgs e)  
 {

    //HACK replace this with a command that toggles to a different tab instead of this tab reference
    MainUserControl mainUserControl = UIHelper.FindChild<MainUserControl>(Application.Current.MainWindow, "root");
    mainUserControl.tabsMain.SelectedItem = mainUserControl.Summary;

    mainUserControl.SummaryUserControl.SelectRadioButton();
  }

Тогда, как предложил Джереми, мое решение было что-то вроде:

public void SelectRadioButton()
{
    // TODO: something like
    myRadioButton.IsChecked = true;
}

Моя структура XAML была похожа на

// my main user control: 
<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...
x:Name="root"
>
<TabControl x:Name="tabsMain" ...> 
<TabItem x:Name="Summary" ... />
</TabControl>
</UserControl>

Я думаю, что комментарии Эндрю Джексона абсолютно верны - в долгосрочной перспективе я планирую исследовать использование перенаправленных команд или перенаправленных событий для обхода визуального дерева, но сейчас я придерживаюсь этого «быстрого и грязного» решения, поскольку мы не грузить этот продукт. Исходя из моего расследования, Routed Events может быть немного излишним для этой ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...