2013-07-18 9 views
8

Ich möchte ein Rechteck in WPF (von Code) und um die Außenseite davon zu füllen. HierFüllen Sie die Außenseite eines Rechtecks ​​

ist ein Beispiel:

enter image description here

Die Außenseite des Rechtecks ​​ist grau (mit geringer Opazität) sowie die Füllung des Rechtecks ​​trasparent.

+0

Es gibt eine Clip-Eigenschaft, die Sie bearbeiten können, um das gewünschte Ergebnis zu erzielen. – Nitesh

Antwort

5

Sie können auch Ihr Bild mit einem halbtransparenten Path Element überlagern, das eine CombinedGeometry verwendet, die eine sehr große äußere Rechteck mit einem inneren Rechteck kombiniert:

<Grid> 
    <Image Name="image" Source="C:\Users\Public\Pictures\Sample Pictures\Koala.jpg"/> 
    <Path Fill="#AAFFFFFF"> 
     <Path.Data> 
      <CombinedGeometry GeometryCombineMode="Xor"> 
       <CombinedGeometry.Geometry1> 
        <RectangleGeometry Rect="0,0,10000,10000"/> 
       </CombinedGeometry.Geometry1> 
       <CombinedGeometry.Geometry2> 
        <RectangleGeometry x:Name="transparentRect" Rect="150,100,200,100"/> 
       </CombinedGeometry.Geometry2> 
      </CombinedGeometry> 
     </Path.Data> 
    </Path> 
</Grid> 

Sie würden nun die Rect-Eigenschaft des Elements transparentRect bei Bedarf programmatisch anpassen.

+0

Ihre Antwort verwendet C# -Syntax-Hervorhebung. Dies ist falsch, da XAML XML ist. Eines der offensichtlichen Probleme ist, dass Elemente und Attribute die gleiche Farbe haben. – Athari

2

Sie können eine Kombination von OpacityMask und DrawingBrush verwenden:

XAML:

<Grid Background="Gray"> 
    <Image Name="image"Source="..."> 
     <Image.OpacityMask> 
      <DrawingBrush x:Name="mask"/> 
     </Image.OpacityMask> 
    </Image> 
</Grid> 

-Code-behind:

private void UpdateOpactiyMask() 
    { 
     Point topLeft = new Point(); 
     Point bottomRight = new Point(image.ActualWidth, image.ActualHeight); 

     GeometryDrawing left = new GeometryDrawing(); 
     left.Brush = borderBrush; 
     left.Geometry = new RectangleGeometry(new Rect(topLeft, new Point(SelectedArea.Left, bottomRight.Y))); 

     GeometryDrawing right = new GeometryDrawing(); 
     right.Brush = borderBrush; 
     right.Geometry = new RectangleGeometry(new Rect(new Point(SelectedArea.Right, topLeft.Y), bottomRight)); 

     GeometryDrawing top = new GeometryDrawing(); 
     top.Brush = borderBrush; 
     top.Geometry = new RectangleGeometry(new Rect(new Point(SelectedArea.Left, topLeft.Y), new Point(SelectedArea.Right, SelectedArea.Top))); 

     GeometryDrawing bottom = new GeometryDrawing(); 
     bottom.Brush = borderBrush; 
     bottom.Geometry = new RectangleGeometry(new Rect(new Point(SelectedArea.Left, SelectedArea.Bottom), new Point(SelectedArea.Right, bottomRight.Y))); 

     GeometryDrawing center = new GeometryDrawing(); 
     center.Brush = selectionBrush; 
     center.Geometry = new RectangleGeometry(SelectedArea); 

     DrawingGroup drawing = new DrawingGroup(); 
     drawing.Children.Add(left); 
     drawing.Children.Add(right); 
     drawing.Children.Add(top); 
     drawing.Children.Add(bottom); 
     drawing.Children.Add(center); 

     mask.Drawing = drawing; 
    } 

SelectedArea ist ein Rect.

2

können Sie verwenden UIElement.Clip Eigenschaft:

<Window x:Class="So17720970_RectangularBoublik.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     SizeToContent="WidthAndHeight"> 
    <Grid Width="500" Height="500"> 
     <Image Source="http://i.stack.imgur.com/Py65S.jpg"/> <!-- image --> 
     <Rectangle Fill="#AA000000">       <!-- selection --> 
      <Rectangle.Clip> 
       <GeometryGroup FillRule="Nonzero">   <!-- selection clip: --> 
        <RectangleGeometry Rect="0 0 500 200"/> <!-- top --> 
        <RectangleGeometry Rect="0 0 100 500"/> <!-- left --> 
        <RectangleGeometry Rect="0 300 500 200"/> <!-- bottom --> 
        <RectangleGeometry Rect="400 0 100 500"/> <!-- right --> 
       </GeometryGroup> 
      </Rectangle.Clip> 
     </Rectangle> 
     <Rectangle StrokeThickness="1" Stroke="Black" StrokeDashArray="1 2" SnapsToDevicePixels="True" 
       Margin="100 200 100 200"/>     <!-- "ants" --> 
    </Grid> 
</Window> 
1

Dies ist eine Variante der Lösung mit OpacityMask. Anstatt es im Code zu tun, geschieht dies in XAML. Außerdem kehrt es die Logik um: Anstatt 4 Rahmenrechtecke zu zeichnen, zieht es 2 Rechtecke übereinander. Schließlich ist die wichtige Eigenschaft dieser Lösung, dass die Größe des zentralen transparenten Rechtecks ​​relativ zur Bildgröße ist (und nicht in absoluten Pixeln). Sie müssen nicht die tatsächliche Bildgröße oder wie sie gestreckt/positioniert ist (besonders wichtig für Stretch = "Uniform"). Hier habe ich die Bildgröße (maskRect) als 1,1 angegeben und verwendete Bruchzahlen als relative Maskengröße und Position (transpRect). Sie können auch die Bildgröße als 100,100 angeben und Prozentwerte für die Maske verwenden (oder sogar die tatsächlichen Pixelwerte verwenden).

  <Grid Background="#FFF4F4F5" > 
      <Image Name="PhotoImage" Source="..."> 
       <Image.OpacityMask> 
        <DrawingBrush> 
         <DrawingBrush.Drawing> 
          <DrawingGroup> 
           <GeometryDrawing> 
            <GeometryDrawing.Geometry> 
             <RectangleGeometry x:Name="maskRect" Rect="0,0,1,1"/> 
            </GeometryDrawing.Geometry> 
            <GeometryDrawing.Brush> 
             <SolidColorBrush Color="#60000000" /> 
            </GeometryDrawing.Brush> 
           </GeometryDrawing> 
           <GeometryDrawing> 
            <GeometryDrawing.Geometry> 
             <RectangleGeometry x:Name="transpRect" Rect=".25,.20,.40,.40"/> 
            </GeometryDrawing.Geometry> 
            <GeometryDrawing.Brush> 
             <SolidColorBrush Color="Black" /> 
            </GeometryDrawing.Brush> 
           </GeometryDrawing> 
          </DrawingGroup> 
         </DrawingBrush.Drawing> 
        </DrawingBrush> 
       </Image.OpacityMask> 
      </Image> 
     </Grid> 
Verwandte Themen