none
WPF - Canvas mit Transparenz an bestimmten Stellen RRS feed

  • Frage

  • Hallo,

    in WPF habe ich eine Canvas mit scharzem Hintergrund angelegt. In die Mitte der Canvas habe ich einen Kreis gezeichnet (mit der Klasse Ellipse). Wie kann ich nun erreichen, dass der Kreis ein "Guckloch" durch die Canvas wird? Also, dass der Kreis selbst transparent gefüllt ist, die Canvas nur unter dem Kreis transparent gefüllt ist und ich so den Hintergrund hinter der Canvas sehen kann?


    • Bearbeitet User95 Mittwoch, 30. Mai 2018 19:35
    Mittwoch, 30. Mai 2018 19:34

Antworten

  • Hi,
    was Du machen willst, kannst Du mit 2 gefüllten Pfaden über (in) einer transparenten Canvas erreichen, die jeweils die Hälfte überdecken und so gestaltet sind, dass in der Mitte das "Loch" nicht überdeckt wird.

    Hier mal ein XAML-Beispiel, welches zeigt, wie ich das meine. Mit dem Slider wird der Text im "Hintergrund" in der Größe skaliert.

    <Window x:Class="Window33"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window33" Height="450" Width="800">
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Canvas Grid.Row="0">
          <Path Fill="Black">
            <Path.Data>
              <PathGeometry Figures="M 300,200 L 0,200 0,0 800,0 800,200 500,200 A 10,10 0 1 0 300,200" />
            </Path.Data>
          </Path>
          <Path Fill="Black">
            <Path.Data>
              <PathGeometry Figures="M 300,200 L 0,200 0,400 800,400 800,200 500,200 A 10,10 0 0 1 300,200" />
            </Path.Data>
          </Path>
        </Canvas>
        <Label Grid.Row="0" Content="Testzeichen" HorizontalAlignment="Center" VerticalAlignment="center">
          <Label.LayoutTransform>
            <ScaleTransform ScaleX="{Binding ElementName=sl, Path=Value}"
                            ScaleY="{Binding ElementName=sl, Path=Value}"/>
          </Label.LayoutTransform>
        </Label>
        <Slider Grid.Row="1" Name="sl" Minimum="1" Maximum="10" Value="1"/>
      </Grid>
    </Window>

    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks


    Donnerstag, 31. Mai 2018 14:02
  • Hallo,

    ich glaube nicht das dies auf dieser Ebene so gehen wird. Direkt in DirectX wäre das schon möglich.

    Ich würde dir vorschlagen den Content den Du sehen willst auch mit in das Canvas zu packen und die Gucklochschablone als schwarzes Bild mit durchsichtigen Loch zu erstellen. Dieser kannst Du sicherlich auch on the fly mache. Wenn Du nun das Loch immer in der Mitte haben willst, kannst Du die Position des Contents darunter verändern. Sonst veränderst Du die Position der Schablone. Dafür muss sie entsprechen größer sein. Doppelte Größe des Canvas sollte genügen. Ist aber natürlich anhängig davon bis wohin das Loch geschoben werden kann


    13 Millionen Schweine landen jährlich im Müll
    Dev Apps von mir: Icon für UWP, UI Strings
    Andere Dev Apps: UWP Community Toolkit Sample App

    Donnerstag, 31. Mai 2018 00:42

Alle Antworten

  • Hallo,

    ich glaube nicht das dies auf dieser Ebene so gehen wird. Direkt in DirectX wäre das schon möglich.

    Ich würde dir vorschlagen den Content den Du sehen willst auch mit in das Canvas zu packen und die Gucklochschablone als schwarzes Bild mit durchsichtigen Loch zu erstellen. Dieser kannst Du sicherlich auch on the fly mache. Wenn Du nun das Loch immer in der Mitte haben willst, kannst Du die Position des Contents darunter verändern. Sonst veränderst Du die Position der Schablone. Dafür muss sie entsprechen größer sein. Doppelte Größe des Canvas sollte genügen. Ist aber natürlich anhängig davon bis wohin das Loch geschoben werden kann


    13 Millionen Schweine landen jährlich im Müll
    Dev Apps von mir: Icon für UWP, UI Strings
    Andere Dev Apps: UWP Community Toolkit Sample App

    Donnerstag, 31. Mai 2018 00:42
  • Also ein Bild wäre keine Option für mich, da diese Schablone bei unterschiedlichsten Auflösungen verwendet werden soll. Daher muss es eine Vektorgrafik sein.

    Kann man vielleicht eine invertierte Form berechnen, die alle Bereiche überdeckt, die nicht durch Canvas Children abgedeckt sind? Dann würde ich diese invertierte Form in schwarz auf eine transparente Canvas zeichnen.

    Donnerstag, 31. Mai 2018 06:59
  • Deswegen sollst Du das Bild auch on the fly erzeugen mit der Größe die gebraucht wird. Eine Vektorgrafik ist nichts anderes. Es wird nur in der Datei selbst beschrieben wie das "Bild" (Abfolge von Pixeln) auszusehen hat. Hier wäre die Beschreibung im Code.

    Mit ist keine Möglichkeit bekannt das so auf UI Ebene zu erreichen.


    13 Millionen Schweine landen jährlich im Müll
    Dev Apps von mir: Icon für UWP, UI Strings
    Andere Dev Apps: UWP Community Toolkit Sample App

    Donnerstag, 31. Mai 2018 13:01
  • Hi,
    was Du machen willst, kannst Du mit 2 gefüllten Pfaden über (in) einer transparenten Canvas erreichen, die jeweils die Hälfte überdecken und so gestaltet sind, dass in der Mitte das "Loch" nicht überdeckt wird.

    Hier mal ein XAML-Beispiel, welches zeigt, wie ich das meine. Mit dem Slider wird der Text im "Hintergrund" in der Größe skaliert.

    <Window x:Class="Window33"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window33" Height="450" Width="800">
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Canvas Grid.Row="0">
          <Path Fill="Black">
            <Path.Data>
              <PathGeometry Figures="M 300,200 L 0,200 0,0 800,0 800,200 500,200 A 10,10 0 1 0 300,200" />
            </Path.Data>
          </Path>
          <Path Fill="Black">
            <Path.Data>
              <PathGeometry Figures="M 300,200 L 0,200 0,400 800,400 800,200 500,200 A 10,10 0 0 1 300,200" />
            </Path.Data>
          </Path>
        </Canvas>
        <Label Grid.Row="0" Content="Testzeichen" HorizontalAlignment="Center" VerticalAlignment="center">
          <Label.LayoutTransform>
            <ScaleTransform ScaleX="{Binding ElementName=sl, Path=Value}"
                            ScaleY="{Binding ElementName=sl, Path=Value}"/>
          </Label.LayoutTransform>
        </Label>
        <Slider Grid.Row="1" Name="sl" Minimum="1" Maximum="10" Value="1"/>
      </Grid>
    </Window>

    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks


    Donnerstag, 31. Mai 2018 14:02