如何创建可以容纳其他UI元素的循环Border
?
这样的事情:
是否有一些简单的方法可以达到类似的效果?
答案 0 :(得分:37)
简单的方法;
<Border x:Name="circularBorder"
CornerRadius="{Binding Path=ActualHeight, ElementName=circularBorder}"
Width="{Binding Path=ActualHeight, ElementName=circularBorder}">
</Border>
现在,您在所有类型的屏幕中都有一个圆形边框
答案 1 :(得分:5)
这适用于MultiValueConverter
:
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:
<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>
并使用如下:
<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
上的样式。
答案 2 :(得分:4)
理想情况下,你可以使用Ellipse
,但遗憾的是它无法直接保存内容。
接下来猜测可能是为Border
创建模板,但Border
没有Template
属性,所以也是如此......
幸运的是,有一个工作回合 - 你可以使用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>
用法:
<ContentControl>
<Border BorderBrush="Black" BorderThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center"
Height="120" Width="120">
<TextBlock FontSize="24" Text="Some Text" />
</Border>
</ContentControl>
答案 3 :(得分:1)
您可以在背景上绘制圆圈并使用填充偏移其内容(它的厚度将绑定到边框的大小)。
答案 4 :(得分:1)
我认为如果你有Width=Height=X
的边框,那么将CornerRadius
设置为X / 2应该会给出正确的结果。
然后填充将沿着0.3 X以防止内部控制越过边缘。可能想用最后一个号码玩一些,现在没有时间来解决它。
答案 5 :(得分:0)
我的解决方案是(但当然,角半径的边框更简单):
<Border Margin="0,15,0,0" Height="75" Width="75">
<Grid Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource PreviousData}}"
Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource PreviousData}}" >
<Ellipse Width="{Binding Path=Width, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Border}}"
Height="{Binding Path=Height, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Border}}"
Stroke="White" StrokeThickness="1"/>
<Border Width="{Binding Path=Width, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Border}}"
Height="{Binding Path=Height, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Border}}"
VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,1,1">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" >
<TextBlock Foreground="White" FontSize="18" FontFamily="{StaticResource RobotoFont}"
FontWeight="DemiBold"
HorizontalAlignment="Center" Text="0"/>
<TextBlock Foreground="White" FontSize="12" FontFamily="{StaticResource ResourceKey=RobotoFont}" FontStyle="Normal"
HorizontalAlignment="Center" Text="Selected"/>
</StackPanel>
</TextBlock>
</Border>
</Grid>
</Border>