Точный OpacityMask

Почему Вы пытаетесь сделать это?

, поскольку это, вероятно, создаст дубликаты (добавляет к $env:path), и проблемы с установкой постоянных/только для чтения объектов, вызывающих ошибки.

был поток по этой теме недавно на microsoft.public.windows.powershell.

, При попытке сбросить состояние сессии, нет никакого способа сделать это, даже с помощью внутреннего объема ($host.EnterNestedPrompt()) из-за способности установить variables/aliases/... во "всем объеме".

12
задан Glorfindel 14 April 2019 в 22:49
поделиться

4 ответа

Действительно интересная проблема - вот что я понял: эффект, который вы испытываете, кажется определяться концепцией / поведением Viewport TileBrush (полное изображение см. в Viewbox ). По-видимому, неявный ограничивающий прямоугольник FrameworkElement (т.е. Canvas в вашем случае) подвергается влиянию / расширению за счет элементов, выходящих за границы тонким образом, то есть

Внутренняя граница получает автоматические размеры 198 от внешней границы (240 - 20 отступов - 2 пикселя, выведенные экспериментально; не знаю их происхождение, но игнорируются прямо сейчас), то есть, если вы укажете это следующим образом, ничего не должно изменение, а использование других значений приводит к графическим изменениям:

<Border Background="LightBlue" Width="198" Height="198">...</Border>

Далее по умолчанию подразумеваются Viewport и ViewportUnits следующим образом:

<DrawingBrush Stretch="None" AlignmentX="Left" AlignmentY="Top" 
    Viewport="0,0,1,1" ViewportUnits="RelativeToBoundingBox">...</DrawingBrush>

Вы устанавливаете размер DrawingBrush путем переопределения Stretch с Нет , сохраняя положение и размер базовой плитки по умолчанию и относительно его ограничивающего прямоугольника . Вдобавок вы (понятно) переопределяете AlignmentX / AlignmentY , которые определяют размещение в базовом тайле, то есть в его ограничивающей рамке. Восстановление их значений по умолчанию Центр уже говорит о том, что маска соответственно смещается, означая, что она должна быть меньше, чем ограничивающая рамка , иначе их было бы нечего центрировать внутри.

] Это можно сделать дальше, изменив ViewportUnits на Absolute , что, конечно, не будет давать графики вообще, пока единицы не будут правильно настроены; опять же, экспериментально следующие явные значения соответствуют автоматическим, в то время как использование других значений приводит к графическим изменениям:

<DrawingBrush Stretch="None" AlignmentX="Center" AlignmentY="Center" 
    Viewport="0,0,202,202" ViewportUnits="Absolute">...</DrawingBrush>

Теперь маска непрозрачности уже правильно согласована с элементом управления . Очевидно, остается одна проблема, так как маска сейчас обрезает линию, что неудивительно, учитывая ее размер и отсутствие какого-либо эффекта Stretch . Соответствующая корректировка его размера и положения решает эту проблему: Обзор визуализации графики , особенно VisualTreeHelper Класс

  • Система макета , особенно Ограничивающие рамки элемента
  • 8
    ответ дан 2 December 2019 в 22:38
    поделиться

    Один обходной путь, который может быть более идеальным, чем ваш текущий, - это просто применить OpacityMask на более высоком уровне. Используя этот демонстрационный код, например, вы можете удалить маску с границы и вместо этого применить ее к окну . После небольшой настройки он подходит правильно:

    <Window.OpacityMask>
      <DrawingBrush AlignmentX="Left" AlignmentY="Top" Stretch="None">
        <DrawingBrush.Drawing>
          <DrawingGroup>
            <GeometryDrawing Brush="#30000000">
              <GeometryDrawing.Geometry>
                <RectangleGeometry Rect="0,0,300,300"/>
              </GeometryDrawing.Geometry>
            </GeometryDrawing>
            <GeometryDrawing Brush="Black">
              <GeometryDrawing.Geometry>
                <RectangleGeometry Rect="92,82,50,50"/>
              </GeometryDrawing.Geometry>
            </GeometryDrawing>
          </DrawingGroup>
        </DrawingBrush.Drawing>
      </DrawingBrush>
    </Window.OpacityMask>
    

    Вам придется написать код для перемещения маски при изменении размера Окна , и по этой причине вам может быть лучше динамически генерировать маску в код программной части.

    Мой вопрос к вам: зачем вам обрабатывать геометрию, выходящую за пределы вашего Canvas ?

    0
    ответ дан 2 December 2019 в 22:38
    поделиться

    На вашем объекте Canvas добавьте ClipToBounds = "True".

    <Canvas ClipToBounds="True">
    
        <Rectangle Canvas.Left="50" Canvas.Top="50" Width="50" Height="50" 
                   Stroke="Red" StrokeThickness="2" 
                   Fill="White" />
        <Line X1="-10" Y1="150" X2="120" Y2="150"
              Stroke="Red" StrokeThickness="2"/>
    
    </Canvas>
    
    1
    ответ дан 2 December 2019 в 22:38
    поделиться

    Поскольку у вас есть части, которые выступают из элемента управления, одна из идей состоит в том, чтобы отделить изображение элемента управления от маски элемента управления.

    <Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    
        <Border Padding="20" Background="DarkGray" Width="240" Height="240"> <!-- user container -->
    
            <Grid> <!-- the control -->
                <Border Background="LightBlue" HorizontalAlignment="Stretch"> <!-- control mask-->
                    <Canvas>
                        <Rectangle Canvas.Left="50" Canvas.Top="50" Width="50" Height="50"
                                   Stroke="Red" StrokeThickness="2"
                                   Fill="White"
                                   />
    
                        <Canvas.OpacityMask>
                            <DrawingBrush Stretch="None" AlignmentX="Left" AlignmentY="Top" TileMode="None">
                                <DrawingBrush.Drawing>
                                    <DrawingGroup>
                                        <GeometryDrawing Brush="#30000000">
                                            <GeometryDrawing.Geometry>
                                                <RectangleGeometry Rect="0,0,200,200" />
                                            </GeometryDrawing.Geometry>
                                        </GeometryDrawing>
                                        <GeometryDrawing Brush="Black">
                                            <GeometryDrawing.Geometry>
                                                <RectangleGeometry Rect="50,50,50,50" />
                                            </GeometryDrawing.Geometry>
                                        </GeometryDrawing>
                                    </DrawingGroup>
                                </DrawingBrush.Drawing>
                            </DrawingBrush>
                        </Canvas.OpacityMask>
                    </Canvas>
                </Border>
    
                <Canvas> <!-- control image-->
                    <Line X1="-10" Y1="150" X2="120" Y2="150" Stroke="Red" StrokeThickness="2"/>
                </Canvas>
            </Grid>
        </Border>
    </Window>
    
    0
    ответ дан 2 December 2019 в 22:38
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: