Как работать с событием SelectionChanged элемента TabControl WPF?

310
17 мая 2018, 12:00

Есть три вкладки у элемента TabControl, на каждой из них есть DataGrid, информация в котором периодически обновляется. Как сделать так, что при смене вкладки, вызывался метод, который запрашивал бы новые данные и обновлял содержимое гридов. Использовала событие SelectionChanged у TabControl, вызывала нужные методы в зависимости от индекса выбранной вкладки, но вкладки просто перестали отображаться.

private void tbAllPages_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        switch (tbAllPages.SelectedIndex)
        {
            case 0:
                UpdateData1();
                break;
            case 1:
                UpdateData2();
                break;
            case 3:
                UpdateData3();
                break;
            default:
                break;
        }
    }
Answer 1

Я бы на вашем месте сделал что то вроде этого:

XAML

В Xaml мы создадим динамически заполняемый TabControl, который будет привязан к коллекции. И его текущей выбранный индекс будет тоже привязан к переменной. Получится что то вроде этого:

<TabControl ItemsSource="{Binding Tabs}" SelectedIndex="{Binding Selected}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Header}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <ListBox ItemsSource="{Binding Content}"/>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

ViewModel

Для начала нам нужна базовая VM, которая реализует INPC:

public class VM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Далее нам нужна некая VM для элементов TabControl, в ней нам надо задать такие свойства, как Header, ну и сам Content. Я лично буду привязывать ListBox, по этому мой Content будет для теста ObservableCollection<string>. Хочу отметить, что для измененяемых значений нужно будет реализовывать INPC. В моем случае здесь все будет статично и самой ObservableCollection будет достаточно. Сам код будет примерно такой:

public class TabViewModel
{
    public string Header { get; set; }
    public ObservableCollection<string> Content { get; set; }
}

Теперь нам понадобиться основная VM, которая будет привязана уже к форме. Ее мы наследуем от ранее созданного класса с INPC. Внутренности будут содержать коллекцию, ее тестовое заполнение, свойство для выбранного индекса и изменение контента при изменение индекса. Код следующий:

public sealed class ViewModel : VM
{
    public ViewModel()
    {
        var testContent = new ObservableCollection<string>{"Value 1", "Value 2", "Value 3"};
        Tabs.Add(new TabViewModel{Header = "Первая вкладка", Content = testContent});
        Tabs.Add(new TabViewModel{Header = "Вторая вкладка", Content = testContent});
    }
    private int selected;
    public int Selected
    {
        get => selected;
        set
        {
            selected = value;
            UpdateContent(value);
            OnPropertyChanged();
        }
    }
    public ObservableCollection<TabViewModel> Tabs { get; set; } = new ObservableCollection<TabViewModel>();
    private void UpdateContent(int tabId)
    {
        //TODO
    }
}

Остается только в UpdateContent() реализовать некую логику для изменения значений. Я к примеру сделаю что то вроде этого:

private void UpdateContent(int tabId)
{
    var item = Tabs[tabId];
    if (tabId == 1)
        item.Content = new ObservableCollection<string> { "Яблоко", "Груша", "Арбуз" };
}

Но, здесь стоит сделать какую нибудь проверку на обновленный контент, чтобы не лезть в базу лишний раз. А то по переключается пользователь по вкладкам и база лежит...

Вот собственно и все, задаем нашу основную ViewModel как DataContext и смотрим результат:

READ ALSO
C# WPF проверка CheckBox по нумерации

C# WPF проверка CheckBox по нумерации

Доброе время суток! Хочу создать окно авторизации, при условии что CheckBox должны быть выделены по очередности

218
Декомпиляция APK в проект Unity

Декомпиляция APK в проект Unity

Подскажите, пожалуйста, есть ли возможность декомпилировать APK файл обратно в проект UnityСо скриптами C#, настройками и прочим-прочим

585
Проблема с Interlocked

Проблема с Interlocked

Изначально нужно было написать поочередный XOR элементов массиваПри реализации через Interlocked

212
Как сделать привязку кнопки- Enter на кнопку Button в WPF C#

Как сделать привязку кнопки- Enter на кнопку Button в WPF C#

Хочу сделать так, чтобы при нажатии кнопки на клавиатуре, срабатывала кнопка из WPFВроде так можно было делать с помощью Label элемента управления

291