views:

1254

answers:

2

I'm needing to create a UserControl, that has a portion of the control's background transparent. The transparent portion is cutout in the shape of a Border with CornerRadius of 2--it's required because of the design.

Here is my code that is not working:

    <UserControl Margin="1" x:Name="Box">
        <UserControl.Resources>
            <Style TargetType="UserControl">
                <Setter Property="Height" Value="16" />
            </Style>
        </UserControl.Resources>
        <Grid>
            <Border CornerRadius="2" BorderThickness="0">
                <Border.Background>
                    <SolidColorBrush Color="Black" Opacity=".3" />
                </Border.Background>
                <Border.OpacityMask>
                    <VisualBrush>
                        <VisualBrush.Visual>
                            <Grid 
                                Background="Black" 
                                Width="{Binding ElementName=Box, Path=ActualWidth}"
                                Height="{Binding ElementName=Box, Path=ActualHeight}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="50" />
                                    <ColumnDefinition />
                                </Grid.ColumnDefinitions>
                                <Border Grid.Column="1" Margin="1" CornerRadius="2" Background="Transparent" BorderThickness="0" />
                            </Grid>
                        </VisualBrush.Visual>
                    </VisualBrush>
                </Border.OpacityMask>
            </Border>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>

                <TextBlock 
                    VerticalAlignment="Center" TextAlignment="Right" FontSize="10" Margin="2"
                    Foreground="White" Text="Property" />

                <TextBlock 
                    Grid.Column="1" VerticalAlignment="Center" TextAlignment="Center" FontSize="10" Margin="2"
                    Text="Value" />
            </Grid>
        </Grid>
    </UserControl>

I made a few changes, so you guys should be able to drop this straight into XamlPad.

For some reason my VisualBrush that is set to the Border's OpacityMask is not working at all. The OpacityMask is just displaying everything fully visible. For a test, I dropped a quick LinearGradientBrush in and it worked as expected.

Is there some issue using VisualBrush and OpacityMask together? What is going wrong here?

Here is a screenshot of what I'm trying to achieve:

ScreenShot

The UserControl are the headers saying Entity No, Progress, Hours, etc. They are black with 30% transparency and have a rounded rectangle opacity mask cutout. I normally use images to render stuff like this, b/c our graphic artist can get crazy with glass-looking effects.

+1  A: 

Hi Jonathan,

Who is the Box in your code? Could you also add an image of what you want to achieve?

Have you tried Paths to get what you want? E.g. the following path:

<Path Stroke="Black" Stretch="Fill" StrokeThickness="1" Fill="#CCCCFF">
    <Path.Data>
     <GeometryGroup FillRule="EvenOdd" >
      <EllipseGeometry Center="40,70" RadiusX="30" RadiusY="30" />              
      <RectangleGeometry Rect="30,55 100 30" />
    </GeometryGroup>
  </Path.Data>
</Path>

Gives you this cutout: alt text

EDIT: Here is one way to achieve your design:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
   <Page.Resources>
      <SolidColorBrush x:Key="FillBrush" Color="Gray" Opacity="0.3"/>
   </Page.Resources>
   <Grid>
   <!-- Set background image here, instead of border-->
      <Border>
         <Border.Background>
            <LinearGradientBrush>
               <GradientStop Color="#FFcacaca"/>
               <GradientStop Offset="1" Color="#FF353535"/>
            </LinearGradientBrush>
         </Border.Background>
      </Border>
   <!-- Content goes here -->
      <Grid>
         <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
         </Grid.ColumnDefinitions>
         <Border
            MinHeight="24"
            MinWidth="100"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Background="{StaticResource FillBrush}"
            CornerRadius="15, 0, 0, 15"
            Padding="0, 0, 5, 0">
            <TextBlock
               HorizontalAlignment="Right"
               VerticalAlignment="Center"
               Foreground="White"
               Text="From"/>
         </Border>
         <Border
            MinHeight="24"
            MinWidth="100"
            Grid.Column="1"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            BorderBrush="{StaticResource FillBrush}"
            BorderThickness="1"
            CornerRadius="0, 15, 15, 0">
            <TextBox
               Margin="5, 0, 5, 0"
               VerticalAlignment="Center"
               Background="Transparent"
               BorderThickness="0"
               Foreground="#2f3740"
               Text="Verylongname, Johnathan"/>
         </Border>
      </Grid>
   </Grid>
</Page>

The main point is to use the two borders and one brush. For header fields you paint border's background and for content fields you paint border's border :).

Cheers, Anvaka.

Anvaka
Sorry, Box was x:Name I had set on the UserControl (I incorrectly took it out of my code going to XamlPad). You can use RelativeSource instead. I'll get a screen shot on my question above. I think my design is too complicate for paths--it involves using images.
Jonathan.Peppers
Jonathan, I've updated the answer.
Anvaka
That will not fly with our graphic artist. The transparent border must be rounded on all 4 sides as in my picture above. Trying your Xaml out in Xamlpad, there is a straight line in the center... This isn't as easy as first thought--that is why I need an opacity mask.
Jonathan.Peppers
A: 

I am using a created Path to create this opacity mask.

You can find the object I use as a mask from this post:

Odd-Shape Geometry

Jonathan.Peppers