0

全部,

我是 WPF 的新手,这似乎是很多人都在努力解决的问题。我已经将以下 XAML 放在一起,然后以编程方式将其加载到代码中。仅使用模板并将其应用于代码实例化的 TabControl 对象。从那里,我生成标签和标签的随机假数据。问题是我的 TabControl 的 ScrollViewer 无限增长,超出了一切,因此不滚动。我试图将树上的所有 VerticalAlignment 设置为“Stretch”,但它没有帮助。我有一种感觉,这是一个简单的问题,它源于将多个定制拼凑在一起并在运行时将它们全部实例化。任何帮助将不胜感激。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
    Title="Window2">
<TabControl>
    <TabControl.Template>
        <ControlTemplate TargetType="TabControl">
            <DockPanel VerticalAlignment="Stretch">
                <ScrollViewer VerticalAlignment="Stretch">
                    <ScrollViewer.Template>
                        <ControlTemplate TargetType="{x:Type ScrollViewer}">
                            <Grid x:Name="Grid" VerticalAlignment="Stretch" Background="{TemplateBinding Background}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*"/>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <Rectangle x:Name="Corner" Grid.Column="0" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
                                <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="1" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
                                <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
                                <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
                            </Grid>
                        </ControlTemplate>
                    </ScrollViewer.Template>
                    <TabPanel x:Name="HeaderPanel"
                          Panel.ZIndex ="1" 
                          KeyboardNavigation.TabIndex="1"
                          Grid.Column="0"
                          Grid.Row="0"
                          Margin="2,2,2,0"
                          IsItemsHost="true"/>
                </ScrollViewer>
                <ContentPresenter x:Name="PART_SelectedContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="{TemplateBinding Padding}" ContentSource="SelectedContent"/>
            </DockPanel>
        </ControlTemplate>
    </TabControl.Template>
</TabControl>

TabControl tabs = new TabControl();
        string xamlPath = System.IO.File.ReadAllText("..\\..\\Resources\\Templates\\Template.xaml");
        Window window = (Window)XamlReader.Parse(xamlPath);
        tabs.Template = ((TabControl)window.Content).Template;

        Random rand = new Random();

        for (int i = 0; i < 100; i++)
        {

            DataTable dataTable = new DataTable();
            for (int x = 0; x < 50; x++) dataTable.Columns.Add(x.ToString(), typeof(double));

            for (int x = 0; x < 50; x++)
            {
                DataRow dataRow = dataTable.NewRow();
                dataTable.Rows.Add(dataRow);
            }
            DataView dataView = new DataView(dataTable);
            for (int x = 0; x < 50; x++)
            {
                for (int y = 0; y < 50; y++) dataView[x][y] = rand.Next()%100;
            }

            DataGrid table = new DataGrid();
            table.ItemsSource = dataView;


            TabItem tab = new TabItem();
            tab.Header = "Tab " + (i+1);
            tab.Content = table;

            tabs.Items.Add(tab);
        }
        tabs.TabStripPlacement = Dock.Left;
        tabs.VerticalAlignment = VerticalAlignment.Stretch;
        tabs.HorizontalAlignment = HorizontalAlignment.Stretch;
        option.canvas.Children.Add(tabs);
4

2 回答 2

0

需要约束 TabControl

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
    Title="Window2">
    <Grid ShowGridLines="False">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <TabControl Grid.Row="0" Grid.Comlumn="0"/>
    </Grid>
</Window>
于 2013-07-09T20:12:29.053 回答
0

编辑:下面是我原来的解决方案。事实证明,问题首先在于使用 Canvas。通过使用 DockPanel,它完全消除了重新计算大小的需要。这类似于 Blam 的回答。

强制画布具有高度/宽度就可以了。它拒绝在布局渲染之前计算高度,因为所有内容都是动态调整大小的,因此 Content 对象内部的顶级 Panel 显然必须具有手动计算的大小。当然,这就是 XAML/C# 障碍所在的地方,它很好地隐藏了问题。

下面的代码是缺少的。在我添加它之后,原始帖子中的 XAML 和 C# 代码都完美匹配。基本上,顶层 Panel 必须有一个大小,以便较低级别的对象在其周围动态调整大小。

option.canvas.Height = OptionTabs.ActualHeight - tab.ActualHeight - tab.Margin.Bottom - tab.Margin.Top;
option.canvas.Width = OptionTabs.ActualHeight - tab.Margin.Right - tab.Margin.Left;
于 2013-07-10T18:54:30.447 回答