【问题标题】:Using a control for OpacityMask使用 OpacityMask 的控件
【发布时间】:2015-05-07 09:01:51
【问题描述】:

我正在编写一个应用程序。我想要一个教程模式,其中应用程序的屏幕变暗,并且允许应用程序的单个功能发光。在我的实际应用程序中,我有许多数据网格和列表框,所以我认为实现这一点的最简单方法可能是用半透明面板覆盖整个屏幕,然后以某种方式使用不透明蒙版通过某些区域的蒙版来突出显示它们在我的应用程序中,而教程解释了它们的作用。唯一的问题是,我无法让不透明蒙版与视觉刷一起使用并挑选出特定对象,例如列表框。下面是我编写的一个示例程序,用于简单地演示我正在尝试做的事情。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Text="Two different text listboxes"/>

    <ListBox Grid.Row="1" Name="myListBox1" Grid.Column="0" VerticalAlignment="Top">
        <ListBoxItem Content="Item 1" Margin="3" Background="Tan"/>
        <ListBoxItem Content="Item 2" Margin="3" Background="Aqua"/>
        <ListBoxItem Content="Item 3" Margin="3" Background="Gold"/>
    </ListBox>

    <ListBox Grid.Row="1" Name="myListBox2" Grid.Column="1" VerticalAlignment="Top">
        <ListBoxItem Content="Item A" Margin="3" Background="Magenta"/>
        <ListBoxItem Content="Item B" Margin="3" Background="Chartreuse"/>
        <ListBoxItem Content="Item C" Margin="3" Background="Chocolate"/>
        <ListBoxItem Content="Item D" Margin="3" Background="Pink"/>
    </ListBox>


    <Button Grid.Row="2" Height="40" Margin="5" Content="Click me" Grid.ColumnSpan="2"/>

    <DockPanel Grid.RowSpan="3" Background="#55000000" Grid.ColumnSpan="2">
        <DockPanel.OpacityMask>
            <VisualBrush Visual="{Binding ElementName=myListBox1}"/>
        </DockPanel.OpacityMask>
    </DockPanel>
</Grid>

谁能给我一些关于如何简单地完成这个面具的提示?

【问题讨论】:

  • 显然从长远来看,我需要能够修改哪个控件正在使用掩码,但现在,我很高兴知道如何让掩码工作。
  • 等我回家后,我会用几个 Rectangles 和 Clip 向你展示一个绝妙的技巧。
  • 我认为最简单的实现方法是将Panel.ZIndex="1"添加到myListBox1
  • 哦,嘿,@SzabolcsDézsi 也有一个很好的主意,将最高 z-index 设置在您想要在半透明背景上弹出的对象上。 +1 :)
  • 是的,这可能真的有效......我想我也可以让它在我更大的应用程序中工作。我得看看。谢谢。

标签: wpf xaml opacitymask


【解决方案1】:

下面是我过去如何做到这一点的一个例子。我将采取额外的步骤,将故事板动画组合在一起,以对一个对象上Clip 的属性更改进行排序,以向您展示它如何在您的教程场景中工作(它在我的上一个项目中做得很好)这样做了。)除了它是星期五,我离开办公室已经迟到了。 :)

PS:忘了提一下,最初我只是将命名的矩形折叠在我想展示的每个控件的顶部,并留有 -5 的边距。一旦他们的可见性切换为可见并且他们返回Rectangle.RenderedGeometry,您就可以抓住Rect,并仅使用xaml 绑定您的几何体。

或者...如果您不需要它是动态的,并且您不介意在最外层的父级上添加 x 层。您总是可以在 Blend 中加载它-> 将 Rectangle 放在最顶部的 z-index 上,这样它就可以用不透明度覆盖所有内容,在突出显示区域上绘制一个 Rectangle -> 选择两者 -> [从顶部文件菜单] 选择对象 -> 选择路径 -> 选择“制作复合路径”,瞧,你有一个形状,你可以打开可见性并在故事板中循环。

如果您有任何问题或希望我向您展示更多使用该概念,请告诉我,您可以在“PresenterForeground”上的StaticResource 上手动更改 Box1、Box2、Box3 等,以查看该概念虽然行动。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="350">
    <Window.Resources>
        <!-- These guys are for example, you could change the StaticResource on the Clip of the Rectangle
             below to reflect the changes here with a property change in a storyboard, or from a trigger, whatever -->
        <Geometry x:Key="Box1">M0,0 L280,0 L280,280 L0,280 z M10,10 L130,10 L130,130 L10,130 z</Geometry>
        <Geometry x:Key="Box2">M0,0 L280,0 L280,280 L0,280 z M150,10 L270,10 L270,130 L150,130 z</Geometry>
        <Geometry x:Key="Box3">M0,0 L280,0 L280,280 L0,280 z M10,150 L130,150 L130,270 L10,270 z</Geometry>
        <Geometry x:Key="Box4">M0,0 L280,0 L280,280 L0,280 z M150,150 L270,150 L270,270 L150,270 z</Geometry>
    </Window.Resources>

        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Grid.Resources>
                <Style TargetType="Rectangle">
                    <Setter Property="Width" Value="100"/>
                    <Setter Property="Height" Value="100"/>
                    <Setter Property="Margin" Value="20"/>
                </Style>
            </Grid.Resources>

            <Rectangle Fill="Red"/>
            <Rectangle Grid.Column="1" Fill="Blue"/>
            <Rectangle Grid.Row="1" Fill="Green"/>
            <Rectangle Grid.Row="1" Grid.Column="1" Fill="Orange"/>

            <!-- This guy is our main foreground to cut visibility to everything else -->
            <Rectangle Name="PresenterForeground" Grid.ColumnSpan="2" Grid.RowSpan="2"
                Fill="#77000000" 
                Height="Auto"
                Width="Auto" 
                Margin="0"
                Clip="{StaticResource Box1}"/>

        </Grid>

</Window>

希望这对您有所帮助,祝您周末愉快,干杯!

【讨论】:

  • 我真的很喜欢你的解决方案。由于我的窗口重新调整大小,我将需要矩形来调整它们所呈现的控件的大小。我试图通过绑定到与我要突出显示的对象位于同一空间中的几何图形来使其工作,但它不起作用。这基本上是我尝试过的: 在要突出显示的对象和 在窗口底部。我做错了什么?
  • @JonD 嗯,去掉第一个的 Fill,因为你只是在抓取 Rect,如果有的话,你可能希望它是 Fill="{x:Null}" 以便 hittestvisibility会经过那个区域,这周我有一个非常忙碌的一周,但我会看看我是否不能稍后再在这里给出一个更详细的例子,只要我不必重新- 写所有东西哈哈,我希望项目没有保密协议,或者我会尝试寻找源代码并分享它,哈哈,这会更容易。
猜你喜欢
  • 1970-01-01
  • 2011-06-26
  • 2019-05-04
  • 2018-06-02
  • 2016-09-28
  • 1970-01-01
  • 2015-04-22
  • 2022-06-13
  • 1970-01-01
相关资源
最近更新 更多