C#、WPF - VisualBrush 和 OpacityMask

发布于 2024-08-15 18:52:30 字数 2813 浏览 7 评论 0原文

我需要创建一个用户控件,该控件的背景部分是透明的。透明部分被剪裁成 CornerRadius 为 2 的边框形状——这是设计所必需的。

这是我的代码不起作用:

    <UserControl Margin="1" x:Name="Box">
        <UserControl.Resources>
            <Style TargetType="UserControl">
                <Setter Property="Height" Value="16" />
            </Style>
        </UserControl.Resources>
        <Grid>
            <Border CornerRadius="2" BorderThickness="0">
                <Border.Background>
                    <SolidColorBrush Color="Black" Opacity=".3" />
                </Border.Background>
                <Border.OpacityMask>
                    <VisualBrush>
                        <VisualBrush.Visual>
                            <Grid 
                                Background="Black" 
                                Width="{Binding ElementName=Box, Path=ActualWidth}"
                                Height="{Binding ElementName=Box, Path=ActualHeight}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="50" />
                                    <ColumnDefinition />
                                </Grid.ColumnDefinitions>
                                <Border Grid.Column="1" Margin="1" CornerRadius="2" Background="Transparent" BorderThickness="0" />
                            </Grid>
                        </VisualBrush.Visual>
                    </VisualBrush>
                </Border.OpacityMask>
            </Border>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>

                <TextBlock 
                    VerticalAlignment="Center" TextAlignment="Right" FontSize="10" Margin="2"
                    Foreground="White" Text="Property" />

                <TextBlock 
                    Grid.Column="1" VerticalAlignment="Center" TextAlignment="Center" FontSize="10" Margin="2"
                    Text="Value" />
            </Grid>
        </Grid>
    </UserControl>

我做了一些更改,所以你们应该能够将其直接放入 XamlPad 中。

由于某种原因,我设置为边框的 OpacityMask 的 VisualBrush 根本无法工作。 OpacityMask 只是显示完全可见的所有内容。为了进行测试,我放入了一个快速的 LinearGradientBrush,它按预期工作。

同时使用 VisualBrush 和 OpacityMask 是否存在问题?这里出了什么问题?

这是我想要实现的目标的屏幕截图:

ScreenShot http://monitor.utopiaselfscan.com/ Screen.png

UserControl 是表示实体编号、进度、小时等的标题。它们是黑色,透明度为 30%,并具有圆角矩形不透明蒙版切口。我通常使用图像来渲染这样的东西,因为我们的图形艺术家可能会对玻璃效果感到疯狂。

I'm needing to create a UserControl, that has a portion of the control's background transparent. The transparent portion is cutout in the shape of a Border with CornerRadius of 2--it's required because of the design.

Here is my code that is not working:

    <UserControl Margin="1" x:Name="Box">
        <UserControl.Resources>
            <Style TargetType="UserControl">
                <Setter Property="Height" Value="16" />
            </Style>
        </UserControl.Resources>
        <Grid>
            <Border CornerRadius="2" BorderThickness="0">
                <Border.Background>
                    <SolidColorBrush Color="Black" Opacity=".3" />
                </Border.Background>
                <Border.OpacityMask>
                    <VisualBrush>
                        <VisualBrush.Visual>
                            <Grid 
                                Background="Black" 
                                Width="{Binding ElementName=Box, Path=ActualWidth}"
                                Height="{Binding ElementName=Box, Path=ActualHeight}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="50" />
                                    <ColumnDefinition />
                                </Grid.ColumnDefinitions>
                                <Border Grid.Column="1" Margin="1" CornerRadius="2" Background="Transparent" BorderThickness="0" />
                            </Grid>
                        </VisualBrush.Visual>
                    </VisualBrush>
                </Border.OpacityMask>
            </Border>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>

                <TextBlock 
                    VerticalAlignment="Center" TextAlignment="Right" FontSize="10" Margin="2"
                    Foreground="White" Text="Property" />

                <TextBlock 
                    Grid.Column="1" VerticalAlignment="Center" TextAlignment="Center" FontSize="10" Margin="2"
                    Text="Value" />
            </Grid>
        </Grid>
    </UserControl>

I made a few changes, so you guys should be able to drop this straight into XamlPad.

For some reason my VisualBrush that is set to the Border's OpacityMask is not working at all. The OpacityMask is just displaying everything fully visible. For a test, I dropped a quick LinearGradientBrush in and it worked as expected.

Is there some issue using VisualBrush and OpacityMask together? What is going wrong here?

Here is a screenshot of what I'm trying to achieve:

ScreenShot http://monitor.utopiaselfscan.com/Screen.png

The UserControl are the headers saying Entity No, Progress, Hours, etc. They are black with 30% transparency and have a rounded rectangle opacity mask cutout. I normally use images to render stuff like this, b/c our graphic artist can get crazy with glass-looking effects.

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

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

发布评论

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

评论(2

萌化 2024-08-22 18:52:30

你代码中的 Box 是谁?您还可以添加一张您想要实现的目标的图片吗?

您是否尝试过 Paths 来获得您想要的东西?例如,以下路径:

<Path Stroke="Black" Stretch="Fill" StrokeThickness="1" Fill="#CCCCFF">
    <Path.Data>
     <GeometryGroup FillRule="EvenOdd" >
      <EllipseGeometry Center="40,70" RadiusX="30" RadiusY="30" />              
      <RectangleGeometry Rect="30,55 100 30" />
    </GeometryGroup>
  </Path.Data>
</Path>

为您提供此剪切:
替代文本 http://img704.imageshack.us/img704/928/cutw.jpg< /a>

编辑: 这是实现设计的一种方法:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Page.Resources>
      <SolidColorBrush x:Key="FillBrush" Color="Gray" Opacity="0.3"/>
   </Page.Resources>
   <Grid>
   <!-- Set background image here, instead of border-->
      <Border>
         <Border.Background>
            <LinearGradientBrush>
               <GradientStop Color="#FFcacaca"/>
               <GradientStop Offset="1" Color="#FF353535"/>
            </LinearGradientBrush>
         </Border.Background>
      </Border>
   <!-- Content goes here -->
      <Grid>
         <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
         </Grid.ColumnDefinitions>
         <Border
            MinHeight="24"
            MinWidth="100"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Background="{StaticResource FillBrush}"
            CornerRadius="15, 0, 0, 15"
            Padding="0, 0, 5, 0">
            <TextBlock
               HorizontalAlignment="Right"
               VerticalAlignment="Center"
               Foreground="White"
               Text="From"/>
         </Border>
         <Border
            MinHeight="24"
            MinWidth="100"
            Grid.Column="1"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            BorderBrush="{StaticResource FillBrush}"
            BorderThickness="1"
            CornerRadius="0, 15, 15, 0">
            <TextBox
               Margin="5, 0, 5, 0"
               VerticalAlignment="Center"
               Background="Transparent"
               BorderThickness="0"
               Foreground="#2f3740"
               Text="Verylongname, Johnathan"/>
         </Border>
      </Grid>
   </Grid>
</Page>

要点是使用两个边框和一个画笔。对于标题字段,您绘制边框的背景;对于内容字段,您绘制边框的边框:)。

干杯,安瓦卡。

Who is the Box in your code? Could you also add an image of what you want to achieve?

Have you tried Paths to get what you want? E.g. the following path:

<Path Stroke="Black" Stretch="Fill" StrokeThickness="1" Fill="#CCCCFF">
    <Path.Data>
     <GeometryGroup FillRule="EvenOdd" >
      <EllipseGeometry Center="40,70" RadiusX="30" RadiusY="30" />              
      <RectangleGeometry Rect="30,55 100 30" />
    </GeometryGroup>
  </Path.Data>
</Path>

Gives you this cutout:
alt text http://img704.imageshack.us/img704/928/cutw.jpg

EDIT: Here is one way to achieve your design:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Page.Resources>
      <SolidColorBrush x:Key="FillBrush" Color="Gray" Opacity="0.3"/>
   </Page.Resources>
   <Grid>
   <!-- Set background image here, instead of border-->
      <Border>
         <Border.Background>
            <LinearGradientBrush>
               <GradientStop Color="#FFcacaca"/>
               <GradientStop Offset="1" Color="#FF353535"/>
            </LinearGradientBrush>
         </Border.Background>
      </Border>
   <!-- Content goes here -->
      <Grid>
         <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
         </Grid.ColumnDefinitions>
         <Border
            MinHeight="24"
            MinWidth="100"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Background="{StaticResource FillBrush}"
            CornerRadius="15, 0, 0, 15"
            Padding="0, 0, 5, 0">
            <TextBlock
               HorizontalAlignment="Right"
               VerticalAlignment="Center"
               Foreground="White"
               Text="From"/>
         </Border>
         <Border
            MinHeight="24"
            MinWidth="100"
            Grid.Column="1"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            BorderBrush="{StaticResource FillBrush}"
            BorderThickness="1"
            CornerRadius="0, 15, 15, 0">
            <TextBox
               Margin="5, 0, 5, 0"
               VerticalAlignment="Center"
               Background="Transparent"
               BorderThickness="0"
               Foreground="#2f3740"
               Text="Verylongname, Johnathan"/>
         </Border>
      </Grid>
   </Grid>
</Page>

The main point is to use the two borders and one brush. For header fields you paint border's background and for content fields you paint border's border :).

Cheers, Anvaka.

愛上了 2024-08-22 18:52:30

我正在使用创建的路径来创建此不透明蒙版。

您可以从这篇文章中找到我用作遮罩的对象:

Odd-Shape Geometry

I am using a created Path to create this opacity mask.

You can find the object I use as a mask from this post:

Odd-Shape Geometry

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