在WPF中剪切边框

era*_*zap 6 wpf clipping clip opacitymask

我需要创建一个圆形ProgressBar模板.

ControlTemplate:

<ControlTemplate TargetType="{x:Type ProgressBar}">
   <Grid x:Name="TemplateRoot" SnapsToDevicePixels="true">                      
     <Rectangle x:Name="PART_Track" Margin="1" Fill="White" />

     <Border x:Name="PART_Indicator" HorizontalAlignment="Left" Margin="1"  >
        <Grid x:Name="Foreground" >
            <Rectangle x:Name="Indicator" Fill="{TemplateBinding Background}" />
            <Grid x:Name="Animation" ClipToBounds="true" >
               <Rectangle x:Name="PART_GlowRect" Fill="#FF86C7EB" 
                          HorizontalAlignment="Left" Margin="-100,0,0,0" Width="100"/>
            </Grid>                             
        </Grid>                                                             
     </Border>

     <Border x:Name="roundBorder" BorderBrush="{TemplateBinding BorderBrush}"
             BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="10" />
     <TextBlock />

  </Grid>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)

这导致:

不正确的剪辑的图像

PART_Indicator左边的LightBlue矩形在哪里(它的宽度在ProgressBar控件内部设置,如此处所示,值为20)和roundBorder.

我需要的是PART_Indicator剪辑它roundBorder,导致类似于:

所需剪辑的图像

She*_*dan 5

有一个ClipToBounds对房地产Border夹在的边界的内容Border,但不幸的是,它并没有"做它在锡说":

<Border CornerRadius="25" BorderBrush="RoyalBlue" BorderThickness="3" Width="300" 
    Height="50" ClipToBounds="True"> <!-- This doesn't work as expected -->
    <Rectangle Fill="SkyBlue" />
</Border>
Run Code Online (Sandbox Code Playgroud)

但是,Rectangle该类还提供了一些可能有用的属性.有没有什么能阻止你使用Rectangle.RadiusXRectangle.RadiusY属性来绕过Rectangle角落?:

<Border CornerRadius="25" BorderBrush="RoyalBlue" BorderThickness="3" Width="300" 
    Height="50">
    <Rectangle RadiusX="23" RadiusY="23" Fill="SkyBlue" />
</Border>
Run Code Online (Sandbox Code Playgroud)

我知道你想要剪掉彩色填充物Rectangle,但你可以使用该Rectangle.Clip属性:

<Border CornerRadius="25" BorderBrush="RoyalBlue" BorderThickness="3" Width="300" 
    Height="50">
    <Grid>
        <Rectangle Name="ClipRectangle" Fill="Green" Margin="50,0,0,0" 
            Visibility="Hidden" />
        <Rectangle RadiusX="23" RadiusY="23" Fill="SkyBlue" Clip="{Binding 
            RenderedGeometry, ElementName=ClipRectangle}" />
    </Grid>
</Border>
Run Code Online (Sandbox Code Playgroud)

这会将彩色RectangleRenderedGeometry其他Rectangle名称夹在一起ClipRectangle......或者当我说这个片段时,也许我应该说这应该剪辑,因为我刚刚发现这只能在WPF设计器中工作,而不是在应用程序运行.

在此输入图像描述

但是,我没时间在这里,所以希望你能找到拼图的最后一块并自己完成.潜在地,您也可以通过数据绑定到设置为on的GradientStop.Offset属性来完成此操作,因此您甚至不需要这个方法.如果我以后可以再看一遍.LinearGradientBrushBackgroundBorderRectangle


更新>>>

我再看看这个Clip Rectangle并且无法解决为什么它只能在Visual Studio Designer中工作.所以,放弃这个想法,你可以尝试这个LinearGradientBrush想法,这同样是好的.首先,定义你的Brush:

<LinearGradientBrush x:Key="ValueBrush" StartPoint="0,0" EndPoint="1,0">
    <GradientStop Offset="0.0" Color="SkyBlue" />
    <GradientStop Offset="0.7" Color="SkyBlue" />
    <GradientStop Offset="0.7" Color="Transparent" />
    <GradientStop Offset="1.0" Color="Transparent" />
</LinearGradientBrush>
Run Code Online (Sandbox Code Playgroud)

现在,我已经硬编码了这些值来产生这个:

在此输入图像描述

从这个代码:

<Border CornerRadius="25" BorderBrush="RoyalBlue" Background="{StaticResource 
    ValueBrush}" BorderThickness="3" Width="300" Height="50" ClipToBounds="True" />
Run Code Online (Sandbox Code Playgroud)

对于您的实际需求,您需要创建一个double属性以将数据绑定到GradientStop.Offset属性,如下所示:

<LinearGradientBrush x:Key="ValueBrush" StartPoint="0,0" EndPoint="1,0">
    <GradientStop Offset="0.0" Color="SkyBlue" />
    <GradientStop Offset="{Binding MidPoint}" Color="SkyBlue" />
    <GradientStop Offset="{Binding MidPoint}" Color="Transparent" />
    <GradientStop Offset="1.0" Color="Transparent" />
</LinearGradientBrush>
Run Code Online (Sandbox Code Playgroud)

现在,只要您提供介于0.0和1.0之间的值,就会创建您的电平表.


era*_*zap 5

使用 OpacityMask 一个更好的解决方案,除了放置在“MainGrid”中的 OuterBorder 之外的所有模板部分都使用不透明蒙版进行裁剪,该蒙版由一个名为“MaskBorder”的对象设置。

“TemplateRoot”存在于 PrograssBar 控件的内部工作中。

  <ControlTemplate TargetType="{x:Type ProgressBar}">
        <Grid x:Name="TemplateRoot">
            <Border x:Name="OuterBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="10">
                <Grid>
                    <Border x:Name="MaskBorder" Background="{TemplateBinding Background}" CornerRadius="9.5" />

                    <Grid x:Name="MainGrid">
                        <Grid.OpacityMask>
                            <VisualBrush Visual="{Binding ElementName=MaskBorder}" />                                   
                        </Grid.OpacityMask>

                        <Rectangle x:Name="PART_Track" Fill="White" />

                        <Border x:Name="PART_Indicator" HorizontalAlignment="Left">                                 
                            <Grid x:Name="Foreground">
                                <Rectangle x:Name="Indicator" Fill="{TemplateBinding Background}" />
                                <Grid x:Name="Animation" ClipToBounds="true">
                                    <Rectangle x:Name="PART_GlowRect" Fill="#FF86C7EB" HorizontalAlignment="Left" Margin="-100,0,0,0" Width="100" />
                                </Grid>
                            </Grid>
                        </Border>                                                                   
                    </Grid>                                                                                                                                     

                </Grid>                         
            </Border>                       
        </Grid>                      
   </ControlTemplate>
Run Code Online (Sandbox Code Playgroud)