WPF DPI rendering issues with two borders - wpf

Enviroment
Win 8, VS 2012, .NET 4, WPF, screen native resolution 1920x1080#96DPI
XAML
<Border BorderThickness="1" BorderBrush="Red" Width="20" Height="20">
<Border BorderThickness="1" BorderBrush="Blue" />
</Border>
The problem
The borders look fine when DPI is 96, but if I change the DPI to 120, the borders are no longer perfectly pixel aligned.
What I have tried
1) Setting the following properties - RenderOptions.EdgeMode="Aliased" SnapsToDevicePixels="True" UseLayoutRounding="True" - on both borders, mitigates the anti-aliasing and bleeding issues from the higher DPI, but the inner border seems to have a 1px margin usually on the right and bottom sides.
2) The following code does not help to work around the problem:
<Grid Width="20" Height="20">
<Border BorderThickness="1" BorderBrush="Red" />
<Border BorderThickness="1" BorderBrush="Blue" Margin="1" />
</Grid>
3) Using Rectangles instead of Borders has the same problem.
4) The problem also persists under a guest Win 7 running in VirtualBox.
5) Edit - This looks a bit better, in that there is no inner margin, but the outer "border" is 2px thick:
<Canvas Width="20" Height="20">
<Polygon Points="0,0 20,0, 20,20, 0,20" StrokeThickness="1" Stroke="Red" RenderOptions.EdgeMode="Aliased" SnapsToDevicePixels="True" UseLayoutRounding="True" />
<Polygon Points="1,1 19,1, 19,19, 1,19" StrokeThickness="1" Stroke="Blue" RenderOptions.EdgeMode="Aliased" SnapsToDevicePixels="True" UseLayoutRounding="True" />
</Canvas>
Question(s)
How do I get the borders to be pixel perfect without any inner margins or anti-alising/bleeding?
I cannot use code-behind to rework the borders sizes when DPI is other than 96. I must stick to XAML only, because I'm trying to create vector icons (based on XAML).

Bravo Microsoft - https://connect.microsoft.com/VisualStudio/feedback/details/798513/wpf-dpi-rendering-issues-with-two-borders
Yet again, this issue will not be addressed nor fixed.

Related

Is there a way to see DropShadowEffect on designtime?

I want to attach a DropShadowEffect on a Border control. I see it on runtime but not in the designer.
<Grid>
<Border Background="LightGray"
BorderBrush="DarkGray"
BorderThickness="1"
ClipToBounds="True"
Width="400"
Height="100">
<Border Background="Transparent"
BorderBrush="Black"
BorderThickness="0,10,0,0"
Margin="0,-11,0,0">
<Border.Effect>
<DropShadowEffect ShadowDepth="0"/>
</Border.Effect>
</Border>
</Border>
</Grid>
It's quite annoying, especially if working on custom control library.
The former and now apparently obsolete DropShadowBitmapEffect works on run- and designtime.
Edit:
This not a duplicate of other questions like Here as it is quite the opposite problem. The shadow effect appears at runtime, but not in the designer. Just try it out with NET-Framework WPF Project and the code above.

Multiple nested borders with rounded corners. How to?

I'd like to display a content enclosed by multiple borders of different colors and with rounded corners. I experimented with corner radius but could never get perfect corners (i.e. adjacent to corners of a parent border) on nested borders. What is the recommended practice in this case, if any?
The following is what I tried:
<Border Grid.Row="1" Grid.Column="1" CornerRadius="3" BorderThickness="3" BorderBrush="#FAFAFA"Background="#FAFAFA" Margin="40,40,40,40" Padding="0">
<Border.Effect>
<DropShadowEffect Color="#1f40618c" />
</Border.Effect>
<StackPanel>
<Border CornerRadius="3" BorderThickness="3" BorderBrush="#696B6D" Background="#696B6D" Margin="0" Padding="0" >
<Border CornerRadius="2.3" BorderThickness="3" BorderBrush="Black" Margin="0" Padding="32,32,32,16" Background="#102F8C">
<Grid />
</Border>
</Border>
</StackPanel>
</Border>
Thanks.
You have to take into account that the BorderThickness adds to the total width or height of a Border control. You can think of it as if half of the border line lies inside the control and half lies outside. On the other hand the CornerRadius is given relative to the center of the border line.
Consequently the difference between the inner and outer radius should be equal to the sum of half of both BorderThicknesses (plus perhaps the outer Padding and the inner Margin).
With your nested borders that have a BorderThickness of 3 each and an outer CornerRadius of also 3 that would result in an inner CornerRadius of 0.
You may simply set the inner CornerRadius to some sensible value and add 3 to that value for the outer one:
<Border BorderBrush="Blue" BorderThickness="3" CornerRadius="6">
<Border BorderBrush="Red" BorderThickness="3" CornerRadius="3">
</Border>
</Border>

How do I put a border around an image in WPF?

I have a StackPanel containing five images and I want to put a black border around each image.
The XAML I have at the moment is:
<Image Name="imgPic1"
Width="100"
Height="75"
Stretch="Fill"
VerticalAlignment="Top" />
I thought I would be just able to put a one-unit margin or padding on the image and set a background color to 000000 but Padding and Background are both invalid for images.
What is an easy way to do this in XAML? Do I really have to put each image inside another control to get a border around it or is there some other trickery I can use?
Simply wrap the Image in a Border control
<Border BorderThickness="1">
<Image Name="imgPic1"
Width="100"
Height="75"
Stretch="Fill"
VerticalAlignment="Top" />
</Border>
You could also provide a style you apply to images that does this if you don't want to do it around every image
Final solution from answer and comments added by Pax:
<Border BorderThickness="1"
BorderBrush="#FF000000"
VerticalAlignment="Top">
<Image Name="imgPic1"
Width="100"
Height="75"
Stretch="Fill"
VerticalAlignment="Top"/>
</Border>
The accepted answer will not work because of the problem described here
https://wpf.2000things.com/2011/04/17/279-adding-a-border-around-an-image-control/
I solved it this way.
<Viewbox>
<Border BorderThickness="3" BorderBrush="Red">
<Image Stretch="None" ></Image>
</Border>
</Viewbox>
I just stumbled upon this post and the other answer did not work right. Maybe because I now use framework 4 and this post is old?
In any case - if someone will see this by chance in the future - here is my answer:
<Border Name="brdSiteLogo"
BorderThickness="2"
BorderBrush="#FF000000"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Margin="12,112,0,0"
Height="128"
Width="128">
<Image Name="imgSiteLogo"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Stretch="Fill"/>
</Border>
The border thickness and brush are important (if you wont choose a color - you will not see the border!!!)
Also, the border should be aligned on your window. The image is "inside" the border, so you can use margins or just stretch it like I did.

Clipping Path on an ImageBrush in Silverlight

Is there a way to put a clipping path on an ImageBrush in Silverlight (not an Image)? I don't see it available from Intellisense, but I'm wondering if there may be a way to do this.
Yet another unpopular "No" answer. The answer is: there is isn't a way to do this.
One possible work around if its vital to create such a brush might be to use a WriteableBitmap. Render an Image using the original source plus the Clip onto a WriteableBitmap then use it as the source to an ImageBrush.
Maybe this will help
I had a problem with an ImageBrush and a Border with a CornerRadius. I couldn't get the Image to fill/clip to fit. I resolved it by moving the ImageBrush to the content of the Border.
Here's the original with the problem:
<Border CornerRadius="0,0,4,4" BorderThickness="0">
<Border.Background>
<ImageBrush ImageSource="/SLTest;component/Resources/background_image.png" Opacity="1" Stretch="UniformToFill" />
</Border.Background>
<ListBox x:Name="lbiMesages"
Opacity="1" BorderThickness="0"
IsHitTestVisible="False"
ItemContainerStyle="{StaticResource ListBoxItemStyle1}"
>
Here's the working version:
<ListBox x:Name="lbiMessages"
Opacity="1" BorderThickness="0"
IsHitTestVisible="False"
ItemContainerStyle="{StaticResource ListBoxItemStyle1}"
>
<ListBox.Template>
<ControlTemplate>
<Border CornerRadius="0,0,4,4" BorderThickness="0">
<Border.Background>
<ImageBrush ImageSource="/SLTest;component/Resources/background_image.png" Opacity="1" Stretch="UniformToFill" />
</Border.Background>
...
</Border>
</ControlTemplate>

Use UIElement as Clip in WPF

Please pardon my ignorance- I'm very new to WPF.
I am looking to implement a minor, visual effect in my application that gives the look of "inner" rounded corners. The window in question has a dark border that encapsulates several UIElements, one of which is a StatusBar, located at the bottom of the window. This StatusBar has a dark background that matches the window's border. Above the StatusBar is a content view, which is currently a Grid- its background is semi-transparent (I think that this is something of a constraint- you can see through the content view to the desktop below). I would like for the content view (represented by the transparent, inner area in the figure below) to have the look of rounded corners, though I expect to have to sort of create the illusion myself.
(Can't post the image because I'm a lurker and not a poster- please find the drawing here)
My first approach was to add a Rectangle (filled with the same, dark color as the border) immediately above the StatusBar and to assign a Border with rounded corners to its OpacityMask (similar to the solution proposed by Chris Cavanagh**). Sadly, the effect that is produced is the exact opposite of that which I am trying to achieve.
I understand that the Clip property can be of use in this sort of situation, but it seems to me that using any sort of Geometry will prove to be inadequate as it won't be dynamically sized to the region in which it resides.
EDIT: Including my XAML:
<Grid Background="{StaticResource ClientBg}" Tag="{Binding OverlayVisible}" Style="{StaticResource mainGridStyle}">
<DockPanel LastChildFill="True">
<!-- Translates to a StackPanel with a Menu and a Button -->
<local:FileMenuView DockPanel.Dock="Top" />
<!-- Translates to a StatusBar -->
<local:StatusView DockPanel.Dock="Bottom" />
<!-- Translates to a Grid -->
<local:ContentView />
</DockPanel>
</Grid>
Any pointers are more than welcome- I'm ready to provide more indepth detail if necessary.
** http://www.dotnetkicks.com/wpf/WPF_easy_rounded_corners_for_anything
EDIT: Now I got what you mean. In fact you can use Path + OpacityMask approach. You have to draw "inverted" path, to use it as opacity mask. But I have simpler and faster solution for you :). Use Border + CornerRadius, and fill the gaps with solid paths. Just try the following code in Kaxaml and let me know if this is what you were looking for:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="240"
Height="320"
AllowsTransparency="True"
Background="Transparent"
WindowStyle="None">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="*"/>
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<Border Background="Black"/>
<Border Grid.Row="1" BorderBrush="Black" BorderThickness="5">
<Grid>
<Border Background="White" CornerRadius="0, 0, 5, 5" Opacity="0.7"/>
<Path
Width="15"
Height="15"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Data="M10,10 L5,10 L5,5 C4.999,8.343 6.656,10 10,10 z"
Fill="Black"
Stretch="Fill"/>
<Path
Width="15"
Height="15"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Data="M10,10 L5,10 L5,5 C4.999,8.343 6.656,10 10,10 z"
Fill="Black"
Stretch="Fill">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="-1"/>
<TranslateTransform X="15"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
</Border>
<Border Grid.Row="2" Background="Black"/>
</Grid>
</Window>
PS: You can simplify this solution by avoiding render transforms, but you got the idea.

Resources