I'm trying to make a custom progress bar in WPF that has two values (the second is always equal to or higher than the first). The basic bar works ok like so:
<wpft:ClippingBorder BorderBrush="{StaticResource Border}"
Background="{StaticResource Background}"
BorderThickness="1" CornerRadius="4">
<Grid Margin="-1" x:Name="Bars">
<Border BorderBrush="{StaticResource Border}"
Background="{Binding Value2Brush}"
BorderThickness="1" CornerRadius="4"
HorizontalAlignment="Left"
Width="{Binding Value2Width}" />
<Border BorderBrush="{StaticResource Border}"
Background="{Binding Value1Brush}"
BorderThickness="1" CornerRadius="4"
HorizontalAlignment="Left"
Width="{Binding Value1Width}" />
</Grid>
</wpft:ClippingBorder>
(Where ClippingBorder
is this. It's used to prevent glitching at the outer corners when the values are near 0.)
The net result is a nice rounded display:
Zoomed view, to more clearly show the rounded corners:
In particular note that both of the inner bars share the same outer border and their right edge curves to the left, just like the outer border.
This works because it draws the longer bar first, then the shorter one on top of it. However, it only works reliably when the brushes are fully opaque -- in particular if Value1Brush
is partially transparent then some of Value2Brush
will show through it, which I don't want.
Ideally, I want the longer bar to only draw that portion of itself that extends beyond the shorter bar -- or equivalently, to set the clipping/opacity mask of the longer bar to be transparent in the area where the shorter bar is drawn.
But I'm not sure how to do that without losing the rounded corners.
Clip
or withOpacityMask
, but I don't know how to do a rounded rect with the former or an inverse mask with the latter. 2. Without using clipping/opacity, produce the same effect; ie. draw only the part of the longer bar that extends past the shorter bar -- but including filling in the "inverse corners" where the bars meet. – Miral