How to create a circle with a hole in a circle in

2019-02-09 22:21发布

问题:

I have created a UserControl which is a ring by superposing 2 circles the small circle being blank and the second behind the smallest being colored.

In my WPF app, I want to put several rings but the small circle does hide other rings. I'd like to see through it and also capture mouse event for ring behind other rings otherwise it's not real rings. Is it possible ?

I tried OpacityMask for small ellipse as pointed by answer to http://social.msdn.microsoft.com/forums/en-US/wpf/thread/551201d1-c5b3-4e17-ae63-625cfbb8bcc4 but still can't see ring behind hole:

<UserControl x:Class="MyUserControls.MyRing"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="150" d:DesignWidth="150" SizeChanged="UserControl_SizeChanged">
    <Grid Height="150" Name="Grid" Width="150" MouseMove="ellipse1_MouseMove">
        <Ellipse Fill="Red" Height="150" Width="150" HorizontalAlignment="Left" Margin="0,0,0,0" Name="ellipse1" Stroke="Black" VerticalAlignment="Top"  >
            <Ellipse.OpacityMask>
                <RadialGradientBrush>
                    <GradientStop Color="#FFB94444" Offset="0.496"/>
                    <GradientStop Color="#00FFFFFF" Offset="0.491"/>
                </RadialGradientBrush>
            </Ellipse.OpacityMask>
        </Ellipse>
        <Ellipse Fill="White" Height="100" Width="100" Margin="25,25,25,0" Name="ellipse2" Stroke="Black" VerticalAlignment="Top" />       
    </Grid>
</UserControl>

回答1:

It looks like you already found your answer (a few years ago), but for anyone else looking to do this, you may want to check out CompositeGeometry:

http://msdn.microsoft.com/en-us/library/ms751808.aspx#combindgeometriessection

Such as:

<Path Fill="Red" Stroke="Black">
    <Path.Data>
        <CombinedGeometry GeometryCombineMode="Xor">
            <CombinedGeometry.Geometry1>
                <EllipseGeometry RadiusX="75" RadiusY="75" Center="75,75" />
            </CombinedGeometry.Geometry1>
            <CombinedGeometry.Geometry2>
                <EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75" />
            </CombinedGeometry.Geometry2>
        </CombinedGeometry>
    </Path.Data>
</Path>

Then IsHitTestVisible="False" should prevent mouse interference, when needed.



回答2:

You could just create a circle with a transparent background and a StrokeThickness in the UserControl.

<UserControl x:Class="WpfApplication1.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Ellipse Width="50" Height="50" Stroke="Blue" StrokeThickness="10" Fill="Transparent"></Ellipse>
    </Grid>
</UserControl>

EDIT: You can set a gradient brush to the stroke as below. You could replace the LinearGradientBrush with any other type of brush as you wish.

<Ellipse Width="50" Height="50" StrokeThickness="10" Fill="Transparent">
    <Ellipse.Stroke>
        <LinearGradientBrush>
            <GradientStop Offset="0" Color="Red"/>
            <GradientStop Offset="1" Color="Green"/>
        </LinearGradientBrush>
    </Ellipse.Stroke>
</Ellipse>


回答3:

Check out this How to create a doughnut with a transparent center?.

Code with path and button under it:

<Grid x:Name="LayoutRoot" Width="109" Height="109">

    <Button Content="Below" Width="100" Height="100" />

    <Path Fill="#FF1F96D8" Stroke="#FF000000"
        Width="109" HorizontalAlignment="Left" Stretch="None"
        Data="M54.5,32.5 C41.245167,32.5 30.5,43.021309 30.5,56         
          30.5,68.978691 41.245167,79.5 54.5,79.5 C67.754837,79.5         
          78.5,68.978691 78.5,56 C78.5,43.021309 67.754837,32.5        
          54.5,32.5 z M54.5,0.5 C84.32338,0.5 108.5,24.676624         
          108.5,54.5 C108.5,84.32338 84.32338,108.5 54.5,108.5         
          24.676624,108.5 0.5,84.32338 0.5,54.5 0.5,24.676624         
          24.676624,0.5 54.5,0.5 z" Height="109" />


</Grid>