wpf 以编程方式更新TabItem可见性时不会触发IsVisibleChanged

9q78igpj  于 2022-11-18  发布在  其他
关注(0)|答案(2)|浏览(226)

我有一个包含三个选项卡的选项卡控件,其中两个选项卡的“可见性”设置为在程序启动时折叠,在某些条件下可见,并且以后可以再次折叠。如果折叠的TabItem是当前选定的选项卡,则即使它已折叠,其内容仍然可见。
选项卡的可见性绑定到我的ViewModel,并以这种方式更新。
我总是希望在选项卡的任何可见性更改时激活第一个选项卡。我尝试过编写一个简单的代码来处理这种情况,但只有在加载/卸载UserControl时才会遇到这种情况。当选项卡的可见性更新时,不会调用处理程序。我尝试在选项卡控件及其项上设置IsVisibleChanged属性,但我无法让代码生效。

这是我的xaml:

<UserControl x:Class="MyNameSpace.MyControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        IsVisibleChanged="TabControl_IsVisibleChanged>
<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/Platform.Presentation;component/Themes/MyTheme.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>
<TabControl x:Name="_tabControl" IsVisibleChanged="TabControl_IsVisibleChanged">
    <TabItem Header="View 1" x:Name="_view1Tab" IsVisibleChanged="TabControl_IsVisibleChanged">
        <local:SingleWorkspaceView/>
    </TabItem>
    <TabItem Header="View 2" x:Name="_view2Tab" Visibility="{Binding TabVisibility}" IsVisibleChanged="TabControl_IsVisibleChanged">
        <local:WorkspaceDeploymentView/>
    </TabItem>
    <TabItem Header="View 3" x:Name="_view3Tab" Visibility="{Binding TabVisibility}" IsVisibleChanged="TabControl_IsVisibleChanged">
        <local:TabDeploymentView/>
    </TabItem>
</TabControl>

下面是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MyNameSpace
{                                               
/// <summary>
/// Interaction logic for TopLevelControl.xaml
/// </summary>
public partial class TopLevelControl : UserControl
{
        ApplicationViewModel _viewModel;
        public TopLevelControl()
        {
            _viewModel = new ApplicationViewModel();
            base.DataContext = _viewModel;
            InitializeComponent();
        }

        private void TabControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
           TabItem tab = sender as TabItem;
           if(tab != null && (bool)e.NewValue)
           {
              _tabControl.SelectedIndex = 0;
           }
        }
     }
 }

是否有某种原因导致事件未触发?

yjghlzjz

yjghlzjz1#

让我们以MVVM的方式完成,不需要任何代码隐藏
xaml这里我们已经绑定了选项卡控件的SelectedIndex="{绑定选项卡选定索引}”

<TabControl SelectedIndex="{Binding TabSelectedIndex}">
        <TabItem Header="abc">
            <Button Content="ok"/>
        </TabItem>
        <TabItem Header="xyz" Visibility="{Binding TabVisibility}">
            <Button Content="ok"/>
        </TabItem>
        <TabItem Header="pqr" Visibility="{Binding TabVisibility}">
            <Button Content="ok"/>
        </TabItem>
    </TabControl>

xaml.cs

public MainWindow()
    {
        InitializeComponent();
        DataContext =new  ViewModel();
    }

检视模型

public class ViewModel: INotifyPropertyChanged
{
    int tabSelectedIndex;
    //this will be bound to the SelectedIndex of Tabcontrol
    public int TabSelectedIndex
    {
        get { return tabSelectedIndex; }
        set { tabSelectedIndex = value;
            Notify("TabSelectedIndex"); 
        }
    }

    Visibility tabVisibility;
    //this will be binded to the Visibility of TabItem 
    public Visibility  TabVisibility
    {
        get { return tabVisibility; }
        set
        {
            tabVisibility = value;
            //this is the logic that will set firstTab selected when Visibility will be collapsed
        if (tabVisibility == Visibility.Collapsed)
        {
            tabSelectedIndex = 0;
            Notify("TabSelectedIndex");
        }
            Notify("TabVisibility"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    void Notify(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
}

我希望这会有帮助。如果会有帮助,那么就说MVVM岩石:)

sc4hvdpw

sc4hvdpw2#

这对我很有效:

private void TabItem_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (sender is TabItem tabItem && tabItem.Parent is TabControl tabControl && tabItem.Visibility == Visibility.Collapsed && tabControl.SelectedItem == tabItem)
    {
        tabControl.SelectedItem = tabControl.Items.Cast<TabItem>().FirstOrDefault(t => t.Visibility == Visibility.Visible);
    }
}

相关问题