最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - WinUI 3: TabView, Tabs overlap Caption buttons - Stack Overflow

programmeradmin3浏览0评论

I tried to make a tabview which is content extended into a custom titlebar

<Grid>
    <TabView x:Name="MyTabView" Background="Transparent" AddTabButtonClick="MyTabView_AddTabButtonClick" TabCloseRequested="MyTabView_TabCloseRequested">

        <TabView.TabStripHeader>
            <Border x:Name="MyCustomMenuRegion" MinWidth="0" Background="Transparent" IsHitTestVisible="False"/>
        </TabView.TabStripHeader>

        <!--Default Home Tab-->
        <TabViewItem Header="Home" Background="Transparent" IsClosable="False" MaxHeight="40" MaxWidth="100">
            <TextBlock Text=""/>
        </TabViewItem>

        <TabView.TabStripFooter>
            <Border x:Name="CustomDragRegion" MinWidth="0" Background="Transparent" IsHitTestVisible="False" SizeChanged="CustomDragRegion_SizeChanged"/>
        </TabView.TabStripFooter>
    </TabView>
</Grid>

I added the usercontrol of this tabView to my UserWindow(MainWindow)

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="40" x:Name="TitleBarRegion"/>
        <RowDefinition Height="*" x:Name="ContentRegion"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" x:Name="ControlRegion"/>
    </Grid.ColumnDefinitions>

    <myUICrl:MyTitleRegionControl x:Name="MyTitleRegion" Grid.Row="0" Grid.Column="0" Canvas.ZIndex="0"/>

    <myUICrl:MyCaptionsRegionControl x:Name="MyCaptionsRegion" Grid.Row="0" Grid.Column="1" Canvas.ZIndex="2" HorizontalAlignment="Right"/>

    <myUICrl:MyTabViewControl x:Name="MyTabView" Grid.Row="0" Grid.Column="0" Canvas.ZIndex="1"/>
</Grid>

I also using the official from Microsoft recommended way to transform the dragrectangle

internal void SetRegionsForCustomTitleBar()
{
    double scale = this.MyTitleRegion.XamlRoot.RasterizationScale;

    // Set the Width of TitleBar
    SetTitleBarWidth(this.AppWindow, this.MyTitleRegion, scale);

    // Set the draggable Area/Region of TitleBar
    SetDraggableArea(this.AppWindow, this.MyTabView, scale);

    // Set the non-draggable Area/Region of CaptionsButton
    SetNonDraggableRegion(this.AppWindow, this.MyCaptionsRegion, scale);
}

private void SetTitleBarWidth(AppWindow myAppWindow, MyTitleRegionControl myTitleRegion, double scale)
{
    myTitleRegion.GetHeaderDefinition().Width = new GridLength(myAppWindow.TitleBar.LeftInset / scale);
    myTitleRegion.GetFooterDefinition().Width = new GridLength(myAppWindow.TitleBar.RightInset / scale);
}

private void SetDraggableArea(AppWindow myAppWindow, MyTabViewControl myTabView, double scale)
{
    Border myCustomDragRegion = myTabView.GetCustomDragRegion();
    GeneralTransform customDragRegionTransform = myCustomDragRegion.TransformToVisual(null);
    Rect customDragRegionBounds = customDragRegionTransform.TransformBounds(new Rect(0, 0, myCustomDragRegion.ActualWidth, myCustomDragRegion.ActualHeight));
    RectInt32 customDragRegionRect = GetRect(customDragRegionBounds, scale);

    myAppWindow.TitleBar.SetDragRectangles(GetRectArray(customDragRegionRect));
}

private void SetNonDraggableRegion(AppWindow myAppWindow, MyCaptionsRegionControl myCaptionsRegion, double scale)
{
    GeneralTransform captionsRegionTransform = myCaptionsRegion.TransformToVisual(null);
    Rect captionsRegionBounds = captionsRegionTransform.TransformBounds(new Rect(0, 0, myCaptionsRegion.ActualWidth, myCaptionsRegion.ActualHeight));
    RectInt32 captionsRegionRect = GetRect(captionsRegionBounds, scale);

    InputNonClientPointerSource nonClientInputSrc = InputNonClientPointerSource.GetForWindowId(myAppWindow.Id);
    nonClientInputSrc.SetRegionRects(NonClientRegionKind.Passthrough, GetRectArray(captionsRegionRect));
}

private RectInt32 GetRect(Rect bounds, double scale)
{
    return new RectInt32
    (
        _X: (int)Math.Round(bounds.X * scale),
        _Y: (int)Math.Round(bounds.Y * scale),
        _Width: (int)Math.Round(bounds.Width * scale),
        _Height: (int)Math.Round(bounds.Height * scale)
    );
}

private RectInt32[] GetRectArray(RectInt32 rect)
{
    return new RectInt32[] { rect };
}

now to my problem: I don't know why but the tabview ignores my CaptionRegionControl and I don't know to tell it to see the control

the result of it is following

I hope somebody knows how to fix it

I tried to make a tabview which is content extended into a custom titlebar

<Grid>
    <TabView x:Name="MyTabView" Background="Transparent" AddTabButtonClick="MyTabView_AddTabButtonClick" TabCloseRequested="MyTabView_TabCloseRequested">

        <TabView.TabStripHeader>
            <Border x:Name="MyCustomMenuRegion" MinWidth="0" Background="Transparent" IsHitTestVisible="False"/>
        </TabView.TabStripHeader>

        <!--Default Home Tab-->
        <TabViewItem Header="Home" Background="Transparent" IsClosable="False" MaxHeight="40" MaxWidth="100">
            <TextBlock Text=""/>
        </TabViewItem>

        <TabView.TabStripFooter>
            <Border x:Name="CustomDragRegion" MinWidth="0" Background="Transparent" IsHitTestVisible="False" SizeChanged="CustomDragRegion_SizeChanged"/>
        </TabView.TabStripFooter>
    </TabView>
</Grid>

I added the usercontrol of this tabView to my UserWindow(MainWindow)

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="40" x:Name="TitleBarRegion"/>
        <RowDefinition Height="*" x:Name="ContentRegion"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" x:Name="ControlRegion"/>
    </Grid.ColumnDefinitions>

    <myUICrl:MyTitleRegionControl x:Name="MyTitleRegion" Grid.Row="0" Grid.Column="0" Canvas.ZIndex="0"/>

    <myUICrl:MyCaptionsRegionControl x:Name="MyCaptionsRegion" Grid.Row="0" Grid.Column="1" Canvas.ZIndex="2" HorizontalAlignment="Right"/>

    <myUICrl:MyTabViewControl x:Name="MyTabView" Grid.Row="0" Grid.Column="0" Canvas.ZIndex="1"/>
</Grid>

I also using the official from Microsoft recommended way to transform the dragrectangle

internal void SetRegionsForCustomTitleBar()
{
    double scale = this.MyTitleRegion.XamlRoot.RasterizationScale;

    // Set the Width of TitleBar
    SetTitleBarWidth(this.AppWindow, this.MyTitleRegion, scale);

    // Set the draggable Area/Region of TitleBar
    SetDraggableArea(this.AppWindow, this.MyTabView, scale);

    // Set the non-draggable Area/Region of CaptionsButton
    SetNonDraggableRegion(this.AppWindow, this.MyCaptionsRegion, scale);
}

private void SetTitleBarWidth(AppWindow myAppWindow, MyTitleRegionControl myTitleRegion, double scale)
{
    myTitleRegion.GetHeaderDefinition().Width = new GridLength(myAppWindow.TitleBar.LeftInset / scale);
    myTitleRegion.GetFooterDefinition().Width = new GridLength(myAppWindow.TitleBar.RightInset / scale);
}

private void SetDraggableArea(AppWindow myAppWindow, MyTabViewControl myTabView, double scale)
{
    Border myCustomDragRegion = myTabView.GetCustomDragRegion();
    GeneralTransform customDragRegionTransform = myCustomDragRegion.TransformToVisual(null);
    Rect customDragRegionBounds = customDragRegionTransform.TransformBounds(new Rect(0, 0, myCustomDragRegion.ActualWidth, myCustomDragRegion.ActualHeight));
    RectInt32 customDragRegionRect = GetRect(customDragRegionBounds, scale);

    myAppWindow.TitleBar.SetDragRectangles(GetRectArray(customDragRegionRect));
}

private void SetNonDraggableRegion(AppWindow myAppWindow, MyCaptionsRegionControl myCaptionsRegion, double scale)
{
    GeneralTransform captionsRegionTransform = myCaptionsRegion.TransformToVisual(null);
    Rect captionsRegionBounds = captionsRegionTransform.TransformBounds(new Rect(0, 0, myCaptionsRegion.ActualWidth, myCaptionsRegion.ActualHeight));
    RectInt32 captionsRegionRect = GetRect(captionsRegionBounds, scale);

    InputNonClientPointerSource nonClientInputSrc = InputNonClientPointerSource.GetForWindowId(myAppWindow.Id);
    nonClientInputSrc.SetRegionRects(NonClientRegionKind.Passthrough, GetRectArray(captionsRegionRect));
}

private RectInt32 GetRect(Rect bounds, double scale)
{
    return new RectInt32
    (
        _X: (int)Math.Round(bounds.X * scale),
        _Y: (int)Math.Round(bounds.Y * scale),
        _Width: (int)Math.Round(bounds.Width * scale),
        _Height: (int)Math.Round(bounds.Height * scale)
    );
}

private RectInt32[] GetRectArray(RectInt32 rect)
{
    return new RectInt32[] { rect };
}

now to my problem: I don't know why but the tabview ignores my CaptionRegionControl and I don't know to tell it to see the control

the result of it is following

I hope somebody knows how to fix it

Share Improve this question edited Mar 23 at 15:56 Jason Aller 3,65228 gold badges41 silver badges39 bronze badges asked Mar 21 at 18:27 Pain NnceraPain Nncera 436 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 0

I suggest you could refer to the Doc: Display TabView tabs in a window's title bar

If your TabView will display in a window's title bar, you should always include a `TabStripFooter` in your TabView and mark it as a draggable region.

    public MainWindow()
        {
            this.InitializeComponent();
            ExtendsContentIntoTitleBar = true;
            SetTitleBar(CustomDragRegion);
            CustomDragRegion.MinWidth = 188;
        }



    <Grid  >

        <TabView AddTabButtonClick="TabView_AddButtonClick" TabCloseRequested="TabView_TabCloseRequested" Loaded="TabView_Loaded" >

            <TabViewItem Header="Home" IsClosable="False">
                <TabViewItem.IconSource>
                    <SymbolIconSource Symbol="Home" />
                </TabViewItem.IconSource>
            </TabViewItem>

            <TabView.TabStripFooter>
                <Grid x:Name="CustomDragRegion" Background="Transparent" />
            </TabView.TabStripFooter>



        </TabView>

    </Grid>

Something like the following should do the trick:

<TabView
    VerticalAlignment="Stretch"
    AddTabButtonClick="TabView_AddTabButtonClick">
    <TabViewItem
        Header="Home"
        IsClosable="False">
        <TabViewItem.IconSource>
            <SymbolIconSource Symbol="Home" />
        </TabViewItem.IconSource>
    </TabViewItem>

    <TabView.TabStripFooter>
        <Grid ColumnDefinitions="*,Auto">
            <Grid x:Name="CustomDragRegion"
                Grid.Column="0"
                MinWidth="128"
                Background="HotPink"
                Loaded="CustomDragRegion_Loaded" />

            <Grid x:Name="CaptionButtonsPadding"
                Grid.Column="1"
                Background="SkyBlue" />
        </Grid>
    </TabView.TabStripFooter>
</TabView>
public MainWindow()
{
    InitializeComponent();
    ExtendsContentIntoTitleBar = true;
    this.SetTitleBar(CustomDragRegion);
}

private void CustomDragRegion_Loaded(object sender, RoutedEventArgs e)
{
    if (sender is not FrameworkElement element ||
        ExtendsContentIntoTitleBar is false)
    {
        return;
    }

    if (element.XamlRoot.RasterizationScale is double scaleAdjustment &&
        scaleAdjustment > 0)
    {
        CaptionButtonsPadding.Width = AppWindow.TitleBar.RightInset / scaleAdjustment;
    }
}

If you need to use your own caption buttons, you just need to set the total width of them to the CaptionButtonsPadding.

发布评论

评论列表(0)

  1. 暂无评论