2011-03-03 57 views
13

我該如何着手創建可容納其他UI元素的圓形BorderWPF Circular Border

事情是這樣的:enter image description here

有沒有達到類似的效果的一些簡單的方法?

回答

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 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的樣式。

+1

儘管我做了略微不同的事,但我的工作原理與此相同,因此我將其標記爲答案。對於任何感興趣的人來說,對於width = W和height = H的文本框,邊界橢圓的寬度爲W * sqrt(2),height = H * sqrt(2) – NVM 2011-03-04 11:45:23

+0

你是一個嚮導!感謝你! – 2011-06-13 18:45:34

1

您可以在背景上繪製圓形並用填充補償它的內容(它的厚度將被綁定到邊框的大小)。

1

我想如果你有一個邊框Width=Height=X,那麼設置CornerRadius爲X/2應該給出正確的結果。

然後,填充將沿着0.3 X,以防止內部控件穿過邊緣。可能想用最後一個號碼玩一些,現在沒有時間去解決。

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> 
+0

我不想硬編碼的大小的橢圓。它應該像邊框一樣展開。 – NVM 2011-03-03 11:48:36

+0

這是TemplateBinding可以提供幫助的地方 - 已經更新了答案 – kiwipom 2011-03-03 19:25:22

+0

橢圓和內容將重疊。 – NVM 2011-03-04 15:44:34

34

簡單的方法來做到這一點;

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

現在你在所有類型的屏幕

具有圓形邊框
+0

簡單的答案之間的方式 – jharr100 2013-11-06 00:28:19

+0

這太好了。我不知道你可以綁定自己。謝謝! – newman 2014-02-11 01:49:30

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>