【问题标题】:What's the right way to create a XAML Border with repeating elements in Silverlight?在 Silverlight 中创建具有重复元素的 XAML 边框的正确方法是什么?
【发布时间】:2014-02-15 19:37:46
【问题描述】:

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

对于垂直部分,我在网格中使用垂直 StackPanel。在 ControlTemplate 中声明了一个圆(与蓝色矩形重叠)。为了产生重复,我复制粘贴了一堆 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 具有平铺功能,因此它会重复 ControlTemplate 本身,而不是我添加单独的 ContentControl?

【问题讨论】:

  • 为什么不使用ListBox
  • 你能创建一个看起来正确的图像并使用它吗?创建大量控件可能会使您的应用程序变慢并增加不必要的开销。而且,除非它的尺寸完美,否则这些点不一定会在所有角落都排列整齐。

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


【解决方案1】:

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

它是由这个 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),它生成的形状看起来几乎是圆形的。您可以试验Rectangles、Margins 等的位置,以控制最终外观。

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

【讨论】:

    【解决方案2】:

    我有一个稍微不同的提议(不仅在 XAML 中):

    让背景成为你的边框。我已经设法做这样的事情:

    它工作得很好,并且自动适应 UIElement 大小,认为可能需要一些时间(不多)来加载(但可以在您启动应用程序时准备好然后重用)。我已经通过 WritableBitmap 完成了 - 只是渲染了我需要的许多元素(冒险是可以使用任何元素 - 星星、三角形,甚至其他图像):

    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>
    

    【讨论】:

      【解决方案3】:

      我建议创建一个单独的UserControl。圈子的数量可以是UserControl 中的Dependencyproperty。然后,您可以使用ItemsControl 重复圆圈。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-20
        • 2011-03-17
        • 1970-01-01
        相关资源
        最近更新 更多