Использование элемента управления для OpacityMask

Я пишу заявку. Я хотел бы иметь учебный режим, в котором экран приложения темнеет и отдельные функции приложения могут просвечивать. В моем реальном приложении у меня есть много таблиц данных и списков, поэтому я подумал, что самый простой способ сделать это - наложить весь экран на полупрозрачную панель, а затем каким-то образом использовать маску непрозрачности, чтобы просмотреть маску в определенных областях, чтобы выделить их в моем приложении, пока учебник объясняет, что они делают. Единственная проблема в том, что я не могу заставить маску непрозрачности работать с визуальной кистью и выделять определенные объекты, такие как Listbox. Ниже приведен пример программы, которую я написал, чтобы просто продемонстрировать, что я пытаюсь сделать.

<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>

Кто-нибудь может дать мне какие-нибудь советы о том, как просто выполнить эту маску?

1 ответ

Итак, вот пример того, как я делал это в прошлом. Я собирался пойти на дополнительный шаг и собрать анимацию раскадровки, чтобы последовательно изменять свойства Clip на одном объекте, чтобы показать вам, как он может работать в вашем учебном сценарии (что он сделал довольно хорошо на последнем проекте, над которым я это делал), за исключением пятницы, и я уже опаздываю, покидая офис.:)

PS: забыл упомянуть, что изначально я просто поместил именованные прямоугольники свалившимися поверх каждого из элементов управления, которые я хотел показать с полем -5. Как только их видимость переключилась на видимую, и они вернули Rectangle.RenderedGeometry, вы можете получить Rect с привязкой для вашей геометрии просто XAML.

Или... Если вам не нужно это динамически, и вы не возражаете против x слоев поверх вашего внешнего родителя. Вы всегда можете загрузить его в Blend -> Поместить Rectangle на самый верхний z-индекс, чтобы он покрыл все непрозрачностью, нарисуйте Rectangle над областью выделения -> Выберите оба -> [Из верхнего меню файла] Выберите Object -> Select Path -> выберите "Make Compound Path" и, вуаля, у вас есть фигура, на которой вы можете просто включить видимость и циклически перемещаться по раскадровке.

Дайте мне знать, если у вас есть какие-либо вопросы или если вы хотите, чтобы я показал вам, как использовать эту концепцию чаще, вы можете вручную изменить Box1, Box2, Box3 и т. Д. На StaticResource на "PresenterForeground", чтобы увидеть концепцию в действии.

<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>

Надеюсь, что это помогает и хороших выходных, ура!

Другие вопросы по тегам