Wpf 如何在UI元素周围创建圆形边框?

Wpf 如何在UI元素周围创建圆形边框?,wpf,wpf-controls,border,Wpf,Wpf Controls,Border,如何创建可以容纳其他UI元素的圆形边框 大概是这样的: <Style TargetType="ContentControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ContentControl">

如何创建可以容纳其他UI元素的圆形
边框

大概是这样的:

        <Style TargetType="ContentControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ContentControl">
                        <Grid>
                            <Ellipse
                Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Stroke="Red" StrokeThickness="3">
                                <Ellipse.Effect>
                                    <DropShadowEffect
                        BlurRadius="18" Direction="-20" ShadowDepth="12" />
                                </Ellipse.Effect>
                            </Ellipse>
                            <ContentPresenter 
                                HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
<Window x:Class="CircleBorderTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CircleBorderTest"
        Title="MainWindow" Height="350" Width="525">
    <local:CircleBorder>
        yeah
    </local:CircleBorder>
</Window>


有什么简单的方法可以达到类似的效果吗?

你可以在背景上画一个圆圈,并用填充物将其内容偏移(它的厚度将与边框的大小有关)。

我认为如果你的边框的宽度=高度=X,那么将
角半径设置为X/2应该会得到正确的结果


然后,填充将沿0.3 X进行,以防止内部控制越过边缘。可能想玩一些最后的数字,现在没有时间来解决它

理想情况下,您可以使用
椭圆
,但不幸的是,它不能直接保存内容

下一个猜测可能是为您的
边框
创建一个模板,但是
边框
没有
模板
属性,所以也没有了

幸运的是,有一个工作循环-您可以使用
ContentControl
,模板如下:

        <Style TargetType="ContentControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ContentControl">
                        <Grid>
                            <Ellipse
                Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Stroke="Red" StrokeThickness="3">
                                <Ellipse.Effect>
                                    <DropShadowEffect
                        BlurRadius="18" Direction="-20" ShadowDepth="12" />
                                </Ellipse.Effect>
                            </Ellipse>
                            <ContentPresenter 
                                HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
<Window x:Class="CircleBorderTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CircleBorderTest"
        Title="MainWindow" Height="350" Width="525">
    <local:CircleBorder>
        yeah
    </local:CircleBorder>
</Window>

用法:

    <ContentControl>
        <Border BorderBrush="Black" BorderThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center"
                    Height="120" Width="120">
            <TextBlock FontSize="24" Text="Some Text" />
        </Border>
    </ContentControl>

这适用于
多值转换器

public class CircleMarginConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var width = (double)values[0];
        var height = (double)values[1];
        var diagonal = Math.Sqrt(width * width + height * height);
        var horzmargin = (diagonal - width) / 2;
        var vertmargin = (diagonal - height) / 2;
        return new Thickness(horzmargin,vertmargin,horzmargin,vertmargin);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
使用以下用户控件:

<UserControl x:Class="CircleBorderTest.CircleBorder"
             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:local="clr-namespace:CircleBorderTest" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.ContentTemplate>
        <DataTemplate DataType="UserControl">
            <DataTemplate.Resources>
                <local:CircleMarginConverter x:Key="CircleMarginConverter"/>
            </DataTemplate.Resources>
            <Grid VerticalAlignment="Center" HorizontalAlignment="Center">
                <ContentPresenter Content="{TemplateBinding Content}">
                    <ContentPresenter.Margin>
                        <MultiBinding Converter="{StaticResource CircleMarginConverter}">
                            <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
                            <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
                        </MultiBinding>
                    </ContentPresenter.Margin>
                </ContentPresenter>
                <Ellipse HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Red" StrokeThickness="1px"/>
            </Grid>            
        </DataTemplate>
    </UserControl.ContentTemplate>
</UserControl>

它的用法如下:

        <Style TargetType="ContentControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ContentControl">
                        <Grid>
                            <Ellipse
                Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Stroke="Red" StrokeThickness="3">
                                <Ellipse.Effect>
                                    <DropShadowEffect
                        BlurRadius="18" Direction="-20" ShadowDepth="12" />
                                </Ellipse.Effect>
                            </Ellipse>
                            <ContentPresenter 
                                HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
<Window x:Class="CircleBorderTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CircleBorderTest"
        Title="MainWindow" Height="350" Width="525">
    <local:CircleBorder>
        yeah
    </local:CircleBorder>
</Window>

是 啊
这将随内容调整大小。实际上,你可以在任何你喜欢的
ContentControl
上使用这个样式。

简单的方法

<Border x:Name="circularBorder" 
   CornerRadius="{Binding Path=ActualHeight, ElementName=circularBorder}" 
   Width="{Binding Path=ActualHeight, ElementName=circularBorder}">
</Border>

现在,在所有类型的屏幕中都有一个圆形边框

我的解决方案是(当然,带有圆角半径的边框更简单):



我不想要椭圆的硬编码大小。它应该像边框一样展开。椭圆和内容会重叠。虽然我做的有点不同,但我的工作原理相同,所以我将此标记为答案。对任何感兴趣的人来说,对于一个宽度为W、高度为H的文本框,一个边界椭圆的宽度为Wsqrt(2),高度为Hsqrt(2)。你是一个向导!谢谢你!答案中最简单的方式这太好了。我不知道你可以约束自己。谢谢