手动调整窗口大小、最大化或恢复时如何调整 TabControl 的大小

发布于 2024-12-13 04:38:41 字数 7747 浏览 2 评论 0原文

我正在使用带有 MVVM 模式的 WPF。当手动调整主窗口大小时,如何调整 WPF TabControl 的大小?当最大化或恢复时,TabControl 也应该调整大小。您能解释一下解决方案的逻辑吗?您能否建议我阅读与此逻辑相关的主题。 在下面的代码中,我使用 TabControl 来实现 MDI 外观,其中 UserControl 添加到 TabControl。

DashboardView.xaml

 <Window x:Class="MyProject.DashboardView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:MyProject"
         Title="Resiable tabcontrol" 
         Width="1064"
         Height="897" 

         WindowState="Normal" 
         WindowStartupLocation="CenterOwner">

    <Window.Resources>
    <local:TabSizeConverter x:Key="tabSizeConverter" />
    <Style TargetType="{x:Type TabItem}">
        <Setter Property="Width">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource tabSizeConverter}">
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, 
                      AncestorType={x:Type TabControl}}" />
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, 
                      AncestorType={x:Type TabControl}}" Path="ActualWidth" />

                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
    </Window.Resources>

   <DockPanel>

    <Menu Name="menu1" VerticalAlignment="Top" Visibility="Visible" 
        DockPanel.Dock="Top" Loaded="menu1_Loaded">
        <Menu.Background>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,0">
                <LinearGradientBrush.GradientStops>
                    <GradientStop Offset="0" Color="White"/>
                    <GradientStop Offset="0" Color="White"/>
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Menu.Background>

        <MenuItem Header="File" Name="mnuTab" >
            <MenuItem Header="List of High School" 
               Click="mnuTab1_Click"/>
            <MenuItem Header="List of University" 
               Click="mnuTab2_Click" InputGestureText="Ctrl-U" />

            <MenuItem Header="Exit" Click="mnuExit_Click" />
        </MenuItem>

     </Menu>

     <Grid Width="Auto" Height="Auto" >
        <TabControl  Name="tcMdi" Visibility="Visible" HorizontalAlignment="Left" 
           VerticalAlignment="Top" ScrollViewer.HorizontalScrollBarVisibility="Auto" 
          ScrollViewer.VerticalScrollBarVisibility="Auto" >
            <TabControl.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,0">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0" Color="White" />
                        <GradientStop Offset="0" Color="White" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </TabControl.Background>
           </TabControl>
         </Grid>
       </DockPanel>
     </Window>

DashboardView.xaml.cs

 namespace MyProject
 {
    public partial class DashboardView : Window
    {
    private Dictionary<string, string> _mdiChildren = new Dictionary<string, string>();
    public DashboardView()
    {
        InitializeComponent();
        WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; 
    }

    private void mnuTab1_Click(object sender, RoutedEventArgs e)
    {
        ListOfHighSchoolView mdiChild = new ListOfHighSchoolView ();
        AddTab(mdiChild);
        txtBackground.Visibility = Visibility.Hidden;
    }

    private void mnuTab2_Click(object sender, RoutedEventArgs e)
    {

        ListOfHighUniversityView mdiChild = new ListOfHighUniversityView ();
        AddTab(mdiChild);
        txtBackground.Visibility = Visibility.Hidden;
    }

     private void mnuExit_Click(object sender, RoutedEventArgs e)
    {
        Application.Current.Shutdown();
    }

    // Add tab item to the tab
    //This is the user control 
    private void AddTab(ITabbedMDI mdiChild)
    {
        //Check if the user control is already opened
        if (_mdiChildren.ContainsKey(mdiChild.UniqueTabName))
        {
            //user control is already opened in tab. 
            //So set focus to the tab item where the control hosted
            foreach (object item in tcMdi.Items)
            {
                TabItem ti = (TabItem)item;
                if (ti.Name == mdiChild.UniqueTabName)
                {
                    ti.Focus();
                    break;
                }
            }
        }
        else
        {
            //the control is not open in the tab item
            tcMdi.Visibility = Visibility.Visible;

            tcMdi.Width = this.ActualWidth;
            tcMdi.Height = this.ActualHeight;


            ((ITabbedMDI)mdiChild).CloseInitiated += new delClosed(CloseTab);

            //create a new tab item
            TabItem ti = new TabItem();
            //set the tab item's name to mdi child's unique name
            ti.Name = ((ITabbedMDI)mdiChild).UniqueTabName;
            //set the tab item's title to mdi child's title
            ti.Header = ((ITabbedMDI)mdiChild).Title;
            //set the content property of the tab item to mdi child
            ti.Content = mdiChild;
            ti.HorizontalContentAlignment = HorizontalAlignment.Stretch;
            ti.VerticalContentAlignment = VerticalAlignment.Top;
            //add the tab item to tab control
            tcMdi.Items.Add(ti);
            //set this tab as selected
            tcMdi.SelectedItem = ti;
            //add the mdi child's unique name in the open children's name list
            _mdiChildren.Add(((ITabbedMDI)mdiChild).UniqueTabName, ((ITabbedMDI)mdiChild).Title);

        }
    }

    private void CloseTab(ITabbedMDI tab, EventArgs e)
    {
        TabItem ti = null;
        foreach (TabItem item in tcMdi.Items)
        {
            if (tab.UniqueTabName == ((ITabbedMDI)item.Content).UniqueTabName)
            {
                ti = item;
                break;
            }
        }
        if (ti != null)
        {
            _mdiChildren.Remove(((ITabbedMDI)ti.Content).UniqueTabName);
            tcMdi.Items.Remove(ti);
            txtBackground.Visibility = Visibility.Visible;
        }
    }

    // Adjust the tab height and weight during load
    private void menu1_Loaded(object sender, RoutedEventArgs e)
    {
        tcMdi.Width = this.ActualWidth;
        tcMdi.Height = this.ActualHeight - 10;
    }
  }
}

Converters.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;

namespace MyProject
{
  public class TabSizeConverter : System.Windows.Data.IMultiValueConverter     
  {         
    public object Convert(object[] values, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture)         
    {             
        TabControl tabControl = values[0] as TabControl;             
        double width = tabControl.ActualWidth / tabControl.Items.Count;             
        //Subtract 1, otherwise we could overflow to two rows.             
        return (width <= 1) ? 0 : (width - 1);         
    }    

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, 
    System.Globalization.CultureInfo culture)         
    {             
        throw new NotSupportedException();         
    }     
  } 
}

I am using WPF with MVVM pattern. How do I resize WPF TabControl when you manually resize Main window? TabControl should also resize when you maximize or restore. Can you please explain the logic as put solution? Can you please suggest me reading topic which is associated with this logic.
On the code below, I am TabControl to achive MDI look and feel, where UserControl gets added to TabControl.

DashboardView.xaml

 <Window x:Class="MyProject.DashboardView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:MyProject"
         Title="Resiable tabcontrol" 
         Width="1064"
         Height="897" 

         WindowState="Normal" 
         WindowStartupLocation="CenterOwner">

    <Window.Resources>
    <local:TabSizeConverter x:Key="tabSizeConverter" />
    <Style TargetType="{x:Type TabItem}">
        <Setter Property="Width">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource tabSizeConverter}">
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, 
                      AncestorType={x:Type TabControl}}" />
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, 
                      AncestorType={x:Type TabControl}}" Path="ActualWidth" />

                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
    </Window.Resources>

   <DockPanel>

    <Menu Name="menu1" VerticalAlignment="Top" Visibility="Visible" 
        DockPanel.Dock="Top" Loaded="menu1_Loaded">
        <Menu.Background>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,0">
                <LinearGradientBrush.GradientStops>
                    <GradientStop Offset="0" Color="White"/>
                    <GradientStop Offset="0" Color="White"/>
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Menu.Background>

        <MenuItem Header="File" Name="mnuTab" >
            <MenuItem Header="List of High School" 
               Click="mnuTab1_Click"/>
            <MenuItem Header="List of University" 
               Click="mnuTab2_Click" InputGestureText="Ctrl-U" />

            <MenuItem Header="Exit" Click="mnuExit_Click" />
        </MenuItem>

     </Menu>

     <Grid Width="Auto" Height="Auto" >
        <TabControl  Name="tcMdi" Visibility="Visible" HorizontalAlignment="Left" 
           VerticalAlignment="Top" ScrollViewer.HorizontalScrollBarVisibility="Auto" 
          ScrollViewer.VerticalScrollBarVisibility="Auto" >
            <TabControl.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,0">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0" Color="White" />
                        <GradientStop Offset="0" Color="White" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </TabControl.Background>
           </TabControl>
         </Grid>
       </DockPanel>
     </Window>

DashboardView.xaml.cs

 namespace MyProject
 {
    public partial class DashboardView : Window
    {
    private Dictionary<string, string> _mdiChildren = new Dictionary<string, string>();
    public DashboardView()
    {
        InitializeComponent();
        WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; 
    }

    private void mnuTab1_Click(object sender, RoutedEventArgs e)
    {
        ListOfHighSchoolView mdiChild = new ListOfHighSchoolView ();
        AddTab(mdiChild);
        txtBackground.Visibility = Visibility.Hidden;
    }

    private void mnuTab2_Click(object sender, RoutedEventArgs e)
    {

        ListOfHighUniversityView mdiChild = new ListOfHighUniversityView ();
        AddTab(mdiChild);
        txtBackground.Visibility = Visibility.Hidden;
    }

     private void mnuExit_Click(object sender, RoutedEventArgs e)
    {
        Application.Current.Shutdown();
    }

    // Add tab item to the tab
    //This is the user control 
    private void AddTab(ITabbedMDI mdiChild)
    {
        //Check if the user control is already opened
        if (_mdiChildren.ContainsKey(mdiChild.UniqueTabName))
        {
            //user control is already opened in tab. 
            //So set focus to the tab item where the control hosted
            foreach (object item in tcMdi.Items)
            {
                TabItem ti = (TabItem)item;
                if (ti.Name == mdiChild.UniqueTabName)
                {
                    ti.Focus();
                    break;
                }
            }
        }
        else
        {
            //the control is not open in the tab item
            tcMdi.Visibility = Visibility.Visible;

            tcMdi.Width = this.ActualWidth;
            tcMdi.Height = this.ActualHeight;


            ((ITabbedMDI)mdiChild).CloseInitiated += new delClosed(CloseTab);

            //create a new tab item
            TabItem ti = new TabItem();
            //set the tab item's name to mdi child's unique name
            ti.Name = ((ITabbedMDI)mdiChild).UniqueTabName;
            //set the tab item's title to mdi child's title
            ti.Header = ((ITabbedMDI)mdiChild).Title;
            //set the content property of the tab item to mdi child
            ti.Content = mdiChild;
            ti.HorizontalContentAlignment = HorizontalAlignment.Stretch;
            ti.VerticalContentAlignment = VerticalAlignment.Top;
            //add the tab item to tab control
            tcMdi.Items.Add(ti);
            //set this tab as selected
            tcMdi.SelectedItem = ti;
            //add the mdi child's unique name in the open children's name list
            _mdiChildren.Add(((ITabbedMDI)mdiChild).UniqueTabName, ((ITabbedMDI)mdiChild).Title);

        }
    }

    private void CloseTab(ITabbedMDI tab, EventArgs e)
    {
        TabItem ti = null;
        foreach (TabItem item in tcMdi.Items)
        {
            if (tab.UniqueTabName == ((ITabbedMDI)item.Content).UniqueTabName)
            {
                ti = item;
                break;
            }
        }
        if (ti != null)
        {
            _mdiChildren.Remove(((ITabbedMDI)ti.Content).UniqueTabName);
            tcMdi.Items.Remove(ti);
            txtBackground.Visibility = Visibility.Visible;
        }
    }

    // Adjust the tab height and weight during load
    private void menu1_Loaded(object sender, RoutedEventArgs e)
    {
        tcMdi.Width = this.ActualWidth;
        tcMdi.Height = this.ActualHeight - 10;
    }
  }
}

Converters.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;

namespace MyProject
{
  public class TabSizeConverter : System.Windows.Data.IMultiValueConverter     
  {         
    public object Convert(object[] values, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture)         
    {             
        TabControl tabControl = values[0] as TabControl;             
        double width = tabControl.ActualWidth / tabControl.Items.Count;             
        //Subtract 1, otherwise we could overflow to two rows.             
        return (width <= 1) ? 0 : (width - 1);         
    }    

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, 
    System.Globalization.CultureInfo culture)         
    {             
        throw new NotSupportedException();         
    }     
  } 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你好,陌生人 2024-12-20 04:38:41

为什么不直接从 TabControl 中删除对齐方式和大小设置并让它自动调整大小呢?

如果你不希望它占据整个空间,你可以设置 Margin 或使用 Grid 控件,以“*”作为行\列宽度​​\高度(高度=“0.5*”的 GridRow 将仅占用可用空间的一半)。

Why don`t you just remove alignments and size settings from TabControl and let it resize automatically?

If you don`t want it to occupy entire space you can set Margin on it or use Grid control with "*" as row\column width\height (a GridRow with Height="0.5*" will occupy only half of avaliable space).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文