在 WPF 中使用 UIElement 作为 Clip

发布于 2024-08-08 10:25:55 字数 1372 浏览 7 评论 0原文

请原谅我的无知 - 我对 WPF 很陌生。

我希望在我的应用程序中实现一个较小的视觉效果,提供“内部”圆角的外观。相关窗口有一个黑色边框,其中封装了多个 UIElement,其中之一是位于窗口底部的 StatusBar。此 StatusBar 具有与窗口边框相匹配的深色背景。 StatusBar 上方是一个内容视图,目前是一个 Grid - 它的背景是半透明的(我认为这是一个限制 - 你可以通过内容视图看到下面的桌面)。我希望内容视图(由下图中透明的内部区域表示)具有圆角的外观,尽管我希望自己能够创建这种幻觉。

(无法发布图片,因为我是潜伏者而不是海报 - 请找到在这里绘制

我的第一个方法是在 StatusBar 的正上方添加一个矩形(填充与边框相同的深色),并为其 OpacityMask 指定一个圆角边框(类似于Chris Cavanagh 提出的解决方案**)。可悲的是,产生的效果与我想要达到的效果完全相反。

我知道 Clip 属性可以在这种情况下使用,但在我看来,使用任何类型的几何图形都将被证明是不够的,因为它不会根据其所在的区域动态调整大小。

编辑:包括我的 XAML:

<Grid Background="{StaticResource ClientBg}" Tag="{Binding OverlayVisible}" Style="{StaticResource mainGridStyle}">

        <DockPanel LastChildFill="True">

            <!-- Translates to a StackPanel with a Menu and a Button -->
            <local:FileMenuView DockPanel.Dock="Top" />

            <!-- Translates to a StatusBar -->
            <local:StatusView DockPanel.Dock="Bottom" />

            <!-- Translates to a Grid -->
            <local:ContentView />

        </DockPanel>

    </Grid>

任何指示都非常受欢迎 - 我准备在必要时提供更深入的细节。

** http://www.dotnetkicks.com/wpf/WPF_easy_rounded_corners_for_anything

Please pardon my ignorance- I'm very new to WPF.

I am looking to implement a minor, visual effect in my application that gives the look of "inner" rounded corners. The window in question has a dark border that encapsulates several UIElements, one of which is a StatusBar, located at the bottom of the window. This StatusBar has a dark background that matches the window's border. Above the StatusBar is a content view, which is currently a Grid- its background is semi-transparent (I think that this is something of a constraint- you can see through the content view to the desktop below). I would like for the content view (represented by the transparent, inner area in the figure below) to have the look of rounded corners, though I expect to have to sort of create the illusion myself.

(Can't post the image because I'm a lurker and not a poster- please find the drawing here)

My first approach was to add a Rectangle (filled with the same, dark color as the border) immediately above the StatusBar and to assign a Border with rounded corners to its OpacityMask (similar to the solution proposed by Chris Cavanagh**). Sadly, the effect that is produced is the exact opposite of that which I am trying to achieve.

I understand that the Clip property can be of use in this sort of situation, but it seems to me that using any sort of Geometry will prove to be inadequate as it won't be dynamically sized to the region in which it resides.

EDIT: Including my XAML:

<Grid Background="{StaticResource ClientBg}" Tag="{Binding OverlayVisible}" Style="{StaticResource mainGridStyle}">

        <DockPanel LastChildFill="True">

            <!-- Translates to a StackPanel with a Menu and a Button -->
            <local:FileMenuView DockPanel.Dock="Top" />

            <!-- Translates to a StatusBar -->
            <local:StatusView DockPanel.Dock="Bottom" />

            <!-- Translates to a Grid -->
            <local:ContentView />

        </DockPanel>

    </Grid>

Any pointers are more than welcome- I'm ready to provide more indepth detail if necessary.

** http://www.dotnetkicks.com/wpf/WPF_easy_rounded_corners_for_anything

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

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

发布评论

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

评论(1

愁以何悠 2024-08-15 10:25:55

编辑:现在我明白你的意思了。事实上你可以使用Path + OpacityMask 的方法。您必须绘制“反向”路径,才能将其用作不透明蒙版。但我为您提供了更简单、更快的解决方案:)。使用 Border + CornerRadius,并用实体路径填充间隙。只需在 Kaxaml 中尝试以下代码,然后让我知道这是否是您正在寻找的内容:

<Window
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Width="240"
   Height="320"
   AllowsTransparency="True"
   Background="Transparent"
   WindowStyle="None">
   <Grid>
      <Grid.RowDefinitions>
         <RowDefinition Height="24"/>
         <RowDefinition Height="*"/>
         <RowDefinition Height="24"/>
      </Grid.RowDefinitions>
      <Border Background="Black"/>
      <Border Grid.Row="1" BorderBrush="Black" BorderThickness="5">
         <Grid>
            <Border Background="White" CornerRadius="0, 0, 5, 5" Opacity="0.7"/>
            <Path
               Width="15"
               Height="15"
               HorizontalAlignment="Left"
               VerticalAlignment="Bottom"
               Data="M10,10 L5,10 L5,5 C4.999,8.343 6.656,10 10,10 z"
               Fill="Black"
               Stretch="Fill"/>
            <Path
               Width="15"
               Height="15"
               HorizontalAlignment="Right"
               VerticalAlignment="Bottom"
               Data="M10,10 L5,10 L5,5 C4.999,8.343 6.656,10 10,10 z"
               Fill="Black"
               Stretch="Fill">
               <Path.RenderTransform>
                  <TransformGroup>
                     <ScaleTransform ScaleX="-1"/>
                     <TranslateTransform X="15"/>
                  </TransformGroup>
               </Path.RenderTransform>
            </Path>
         </Grid>
      </Border>
      <Border Grid.Row="2" Background="Black"/>
   </Grid>
</Window>

PS:您可以通过避免渲染转换来简化此解决方案,但您已经明白了。

EDIT: Now I got what you mean. In fact you can use Path + OpacityMask approach. You have to draw "inverted" path, to use it as opacity mask. But I have simpler and faster solution for you :). Use Border + CornerRadius, and fill the gaps with solid paths. Just try the following code in Kaxaml and let me know if this is what you were looking for:

<Window
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Width="240"
   Height="320"
   AllowsTransparency="True"
   Background="Transparent"
   WindowStyle="None">
   <Grid>
      <Grid.RowDefinitions>
         <RowDefinition Height="24"/>
         <RowDefinition Height="*"/>
         <RowDefinition Height="24"/>
      </Grid.RowDefinitions>
      <Border Background="Black"/>
      <Border Grid.Row="1" BorderBrush="Black" BorderThickness="5">
         <Grid>
            <Border Background="White" CornerRadius="0, 0, 5, 5" Opacity="0.7"/>
            <Path
               Width="15"
               Height="15"
               HorizontalAlignment="Left"
               VerticalAlignment="Bottom"
               Data="M10,10 L5,10 L5,5 C4.999,8.343 6.656,10 10,10 z"
               Fill="Black"
               Stretch="Fill"/>
            <Path
               Width="15"
               Height="15"
               HorizontalAlignment="Right"
               VerticalAlignment="Bottom"
               Data="M10,10 L5,10 L5,5 C4.999,8.343 6.656,10 10,10 z"
               Fill="Black"
               Stretch="Fill">
               <Path.RenderTransform>
                  <TransformGroup>
                     <ScaleTransform ScaleX="-1"/>
                     <TranslateTransform X="15"/>
                  </TransformGroup>
               </Path.RenderTransform>
            </Path>
         </Grid>
      </Border>
      <Border Grid.Row="2" Background="Black"/>
   </Grid>
</Window>

PS: You can simplify this solution by avoiding render transforms, but you got the idea.

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