1

我有一个 TabControl,我想要一个预览窗口,就像 Windows 7 中的任务栏一样。

当我将鼠标悬停在 tabItem1 上时,我得到了我想要的结果。当我选择第二个或第三个选项卡(tabItem1 的内容现在不可见)然后将鼠标悬停在 tabItem1 上时,我希望看到相同的预览。但现在内容不成比例。我究竟做错了什么?

我有以下主窗口:

<Window.Resources>
    <Style x:Key="TabItemContainerStyle" TargetType="{x:Type TabItem}">
        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Label Content="{Binding}">
                        <Label.Style>
                            <Style TargetType="Label">
                                <EventSetter Event="MouseEnter" Handler="TabItem_MouseEnter"/>
                                <EventSetter Event="MouseLeave" Handler="TabItem_MouseLeave"/>
                            </Style>
                        </Label.Style>
                    </Label>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Window.Resources>
<Grid>
    <TabControl Name="tabControl" ItemContainerStyle="{StaticResource TabItemContainerStyle}" Grid.Row="1">
        <TabItem Header="tabItem1" Name="tabItem1">
            <Grid>
                <Grid Name="grid1" Background="#4700D700">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0*" />
                        <ColumnDefinition Width="200*" />
                    </Grid.ColumnDefinitions>
                    <Label Content="Hello, world!" Height="28" HorizontalAlignment="Left" Margin="37,29,0,0" Name="label1" VerticalAlignment="Top" Grid.Column="1" />
                </Grid>
            </Grid>
        </TabItem>
        <TabItem Header="Tab 2"></TabItem>
        <TabItem Header="Tab 3"></TabItem>
    </TabControl>
</Grid>

这是背后的代码:

public partial class MainWindow : Window
{
    private Window _previewWindow;

    public MainWindow()
    {
        InitializeComponent();
    }

    private static TabItem GetTabItem(object sender)
    {
        var control = sender as Control;
        if (control == null)
            return null;
        var parent = control.TemplatedParent as ContentPresenter;
        if (parent == null)
            return null;
        return parent.TemplatedParent as TabItem;
    }

    void previewWindow_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        var window = sender as Window;
        if (window != null)
            window.Top -= window.ActualHeight;
    }

    private void TabItem_MouseEnter(object sender, MouseEventArgs e)
    {
        var tabItem = GetTabItem(sender);

        if (tabItem != null)
        {
            var vb = new VisualBrush(tabItem.Content as Visual)
            {
                Viewport = new Rect(new Size(160, 80)),
                Viewbox = new Rect(new Size(160, 80)),
            };

            var myRectangle = new Rectangle
            {
                Width = 160,
                Height = 80,
                Stroke = Brushes.Transparent,
                Margin = new Thickness(0, 0, 0, 0),
                Fill = vb
            };

            Point renderedLocation = ((Control)sender).TranslatePoint(new Point(0, 0), this);

            _previewWindow = new Window
            {
                WindowStyle = WindowStyle.ToolWindow,
                SizeToContent = SizeToContent.WidthAndHeight,
                ShowInTaskbar = false,
                Content = myRectangle,
                Left = renderedLocation.X + Left,
                Top = renderedLocation.Y + Top,
            };
            // Top can only be calculated when the size is changed to the content, 
            // therefore the SizeChanged-event is triggered.
            _previewWindow.SizeChanged += previewWindow_SizeChanged;
            _previewWindow.Show();
        }

        e.Handled = true;
    }

    private void TabItem_MouseLeave(object sender, MouseEventArgs e)
    {
        if (_previewWindow != null)
            _previewWindow.Close();
        _previewWindow = null;
    }
}
4

0 回答 0