在Silverlight中使用重复元素创建XAML边框的正确方法是什么?

时间:2014-02-15 19:37:47

标签: silverlight xaml windows-phone-7 windows-phone-8 windows-phone

我正在尝试创建一个蓝色背景和重复圆圈的边框。举个例子:

enter image description here

对于垂直部分,我在网格中使用垂直StackPanel。在ControlTemplate中声明一个圆(重叠蓝色矩形)。为了产生重复,我复制粘贴了一堆ContentControl,每个ContentControl都指向我的ControlTemplate。

例如:

<StackPanel
    Grid.Row="0"
    Grid.RowSpan="3"
    Grid.Column="0"
    Orientation="Vertical"
    >
    <ContentControl
        attachedProperties:LightEllipseAttachedProperties.LightState="{Binding ElementName=PhoneApplicationPage, Path=GameController.Instance.Lights}"
        Template="{StaticResource LightbulbTemplate}"
        />

    **Repeat N times**

    <ContentControl
        attachedProperties:LightEllipseAttachedProperties.LightState="{Binding ElementName=PhoneApplicationPage, Path=GameController.Instance.Lights}"
        Template="{StaticResource LightbulbTemplate}"
        />
</StackPanel>


<ControlTemplate
    x:Key="LightbulbTemplate"
    >
    <Grid>
        <VisualStateManager.VisualStateGroups>

        </VisualStateManager.VisualStateGroups>
        <Rectangle
            Fill="#3300CC"
            Height="15"
            Width="15"
            />
        <Ellipse
            x:Name="LightEllipse"
            Height="8"
            Width="8"
            >
            <Ellipse.Fill>
                <SolidColorBrush />
            </Ellipse.Fill>
        </Ellipse>
    </Grid>
</ControlTemplate>

我的问题:有没有更好的方法使用Silverlight创建重复元素的边框?也许Border有一个Tiling功能,所以它会重复ControlTemplate本身,而不是我添加单独的ContentControls?

3 个答案:

答案 0 :(得分:3)

如果您想要一种简单的方法来构建这样的形状,您可以尝试将Rectangle与自定义StrokeDashArray一起使用:

Example 它是由这个XAML代码生成的:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" Height="200">
    <Rectangle StrokeThickness="14" StrokeDashCap="Round" Stroke="#FF00B2E6" />
    <Rectangle StrokeDashArray="0.1 1.3" 
            StrokeThickness="10" StrokeDashCap="Round" Margin=".9"  >
        <Rectangle.Stroke>
            <SolidColorBrush Color="#BFFF0606"/>
        </Rectangle.Stroke>
    </Rectangle>
</Grid>

XAML使用2个矩形。一个是“背景”颜色,另一个是圆圈。通过试验StrokeDashArray值,您可以控制短划线的形状以及到下一个短划线的距离。通过使用Round短划线帽和小短划线(.1),它会生成一个看起来几乎圆的形状。您可以尝试RectangleMargin等的位置来控制最终外观。

使用这种技术的好处在于它在手机上绘制形状非常有效,它会根据需要自动调整大小。

答案 1 :(得分:2)

我的提案略有不同(不仅仅是在XAML中):

让背景成为你的边界。我设法做了这样的事情:

border

它工作得非常好并且自动适合UIElement大小,可能需要一些时间(不多)加载(但可以在启动应用程序然后重复使用时准备)。我是通过WritableBitmap完成的 - 只是渲染了我需要的许多元素(可能使用的任何元素 - 星星,tringles,甚至其他图像):

private WriteableBitmap CreateBorderBrush(int width, int height)
{
   Rectangle firstBrush = new Rectangle();
   firstBrush.Width = 15;
   firstBrush.Height = 15;
   firstBrush.Fill = new SolidColorBrush(Colors.Blue);
   Ellipse secondBrush = new Ellipse();
   secondBrush.Width = 8;
   secondBrush.Height = 8;
   secondBrush.Fill = new SolidColorBrush(Colors.Orange);
   int dimensionX = width - width % 15;
   int dimensionY = height - height % 15;
   WriteableBitmap bitmapToBrush = new WriteableBitmap(dimensionX, dimensionY);
   for (int i = 0; i < width / 15; i++)
   {
       bitmapToBrush.Render(firstBrush, new TranslateTransform() { X = i * 15, Y = 0 });
       bitmapToBrush.Render(secondBrush, new TranslateTransform() { X = i * 15 + 3, Y = 3 });
   }
   for (int i = 1; i < height / 15 - 1; i++)
   {
       bitmapToBrush.Render(firstBrush, new TranslateTransform() { X = 0, Y = i * 15 });
       bitmapToBrush.Render(secondBrush, new TranslateTransform() { X = 3, Y = i * 15 + 3 });
       bitmapToBrush.Render(firstBrush, new TranslateTransform() { X = dimensionX - 15, Y = i * 15 });
       bitmapToBrush.Render(secondBrush, new TranslateTransform() { X = dimensionX - 15 + 3, Y = i * 15 + 3 });
   }
   for (int i = 0; i < width / 15; i++)
   {
       bitmapToBrush.Render(firstBrush, new TranslateTransform() { X = i * 15, Y = dimensionY - 15 });
       bitmapToBrush.Render(secondBrush, new TranslateTransform() { X = i * 15 + 3, Y = dimensionY - 15 + 3 });
   }
   bitmapToBrush.Invalidate();
   return bitmapToBrush;
}

在MainPage构造函数中,我使用过它:

this.Loaded += (s, e) =>
{
    myGrid.Background = new ImageBrush() { ImageSource = CreateBorderBrush((int)myGrid.ActualWidth, (int)myGrid.ActualHeight) };
};

和XAML代码:

<Grid Name="myGrid" Grid.Row="0" Width="300" Height="200">
     <Button x:Name="first" Content="Button" Width="150" Height="100"/>
</Grid>

答案 2 :(得分:1)

我建议创建一个单独的UserControl。圈数可以是Dependencyproperty的{​​{1}}。然后,您可以使用UserControl重复圈子。