【问题标题】:Silverlight border from images图像中的 Silverlight 边框
【发布时间】:2013-08-03 09:24:30
【问题描述】:

我想做一个通用控件,它有漂亮的边框和内部内容展示器(这将是:左上角)

这是我选择的一种方式,因为没有平铺的图像画笔。 我已经预定义了图块(10 个对于我的应用程序中的所有场景都足够了)。它可以工作,但是我必须明确指定此边框控件的宽度/高度,因为预定义的图块正在扩大网格。有没有办法让它根据内容的宽度/高度自动调整大小,或者一些不同的更优雅的方式?

<sfc:UserControlEx x:Class="Barbar.D20.SilverClient.Views.Controls.UI.Border"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sfc="clr-namespace:Barbar.SilverFramework.Controls;assembly=Barbar.SilverFramework"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <Grid>
        <Image Source="/Images/Border/border-left-top.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Top" />
        <Image Source="/Images/Border/border-right-top.png" Stretch="None" HorizontalAlignment="Right" VerticalAlignment="Top" />
        <Image Source="/Images/Border/border-left-bottom.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
        <Image Source="/Images/Border/border-right-bottom.png" Stretch="None" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
        <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="25,0,25,0" Orientation="Horizontal">
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
            <Image Source="/Images/Border/border-top.png" Stretch="None" />
        </StackPanel>
        <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,25,0,25" Orientation="Vertical">
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
            <Image Source="/Images/Border/border-left.png" Stretch="None" />
        </StackPanel>
        <StackPanel HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,25,0,25" Orientation="Vertical">
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
            <Image Source="/Images/Border/border-right.png" Stretch="None" />
        </StackPanel>    
        <StackPanel HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="25,0,25,0" Orientation="Horizontal">
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
        </StackPanel>

        <ContentPresenter x:Name="contentPresenter" Margin="25,25,25,25" Width="Auto" Height="Auto" />
    </Grid>
</sfc:UserControlEx>


using System.Windows.Markup;
using Barbar.SilverFramework.Controls;
[ContentProperty("UserContent")]
public partial class Border : UserControlEx {
  public Border() {
    InitializeComponent();
  }

  public object UserContent {
    get { return contentPresenter.Content; }
    set { contentPresenter.Content = value; }
  }
}

编辑: 我最终得到了这个解决方案(创建我自己的“隐藏”结果大小的 StackPanel),由于在内容控件中引用了 x:Name="" 项,我也从 UserControl 移动到了 ContentControl;如果有人知道更优雅的方式,我想知道:

using System;
using System.Windows;
using System.Windows.Controls;
namespace Barbar.SilverFramework.Controls {
  public class NoSizeStackPanel : Panel {
    public static readonly DependencyProperty OrientationProperty =
              DependencyProperty.Register(
            "Orientation",
            typeof(Orientation),
            typeof(NoSizeStackPanel),
            new PropertyMetadata(Orientation.Horizontal, null));

    public Orientation Orientation {
      get {
        return (Orientation)base.GetValue(NoSizeStackPanel.OrientationProperty);
      }
      set {
        base.SetValue(NoSizeStackPanel.OrientationProperty, value);
      }
    }


    protected override Size MeasureOverride(Size availableSize) {
      var children = Children;
      for (int i = 0; i < children.Count; i++) {
        children[i].Measure(availableSize);
      }
      return new Size(0, 0);
    }

    protected override Size ArrangeOverride(Size finalSize) {
      // Get the collection of children
      var children = Children;
      double w = 0;
      double h = 0;
      double mh = 0;
      double mw = 0;
      for (int i = 0; i < children.Count; i++) {
        var point = (Orientation == Orientation.Horizontal) ?
           new Point(w, 0) : new Point(0, h);

        double dw = children[i].DesiredSize.Width;
        double dh = children[i].DesiredSize.Height;

        mh = Math.Max(mh, dh);
        mw = Math.Max(mw, dw);

        w += dw;
        h += dh;

        children[i].Arrange(new Rect(point.X, point.Y, dw, dh));
      }

      return (Orientation == Orientation.Horizontal) ?
        new Size(w, mh) : new Size(mw, h);
    }
  }
}

using System.Windows.Controls;
namespace Barbar.D20.SilverClient.Views.Controls.UI {
  public class Border : ContentControl {
    public Border() {
      this.DefaultStyleKey = typeof(Border);
    }
  }
}

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:sfc="clr-namespace:Barbar.SilverFramework.Controls;assembly=Barbar.SilverFramework"
    xmlns:ui="clr-namespace:Barbar.D20.SilverClient.Views.Controls.UI"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="ui:Border">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ui:Border">
                    <Grid>
                        <Image Source="/Images/Border/border-left-top.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Top" />
                        <Image Source="/Images/Border/border-right-top.png" Stretch="None" HorizontalAlignment="Right" VerticalAlignment="Top" />
                        <Image Source="/Images/Border/border-left-bottom.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
                        <Image Source="/Images/Border/border-right-bottom.png" Stretch="None" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
                        <sfc:NoSizeStackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="25,0,25,0">
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                            <Image Source="/Images/Border/border-top.png" Stretch="None" />
                        </sfc:NoSizeStackPanel>
                        <sfc:NoSizeStackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,25,0,25" Orientation="Vertical">
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                            <Image Source="/Images/Border/border-left.png" Stretch="None" />
                        </sfc:NoSizeStackPanel>
                        <sfc:NoSizeStackPanel HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,25,0,25" Orientation="Vertical">
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                            <Image Source="/Images/Border/border-right.png" Stretch="None" />
                        </sfc:NoSizeStackPanel>
                        <sfc:NoSizeStackPanel HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="25,0,25,0">
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                            <Image Source="/Images/Border/border-bottom.png" Stretch="None" />
                        </sfc:NoSizeStackPanel>
                        <ContentPresenter Margin="25,25,25,25" Width="Auto" Height="Auto" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

【问题讨论】:

    标签: silverlight xaml silverlight-5.0


    【解决方案1】:

    您可以将ImageStretch 属性与Fill 值一起使用。使用RenderTransform,您只能使用 3 张图片...

    <Grid>
        <Image
            Source="/Images/top.png"
            Height="25"
            Margin="25,0"
            Stretch="Fill"
            VerticalAlignment="Top"/>
        <Image
            Source="/Images/top.png"
            Height="25"
            Margin="25,0"
            Stretch="Fill"
            VerticalAlignment="Bottom"
            RenderTransformOrigin="0.5,0.5">
            <Image.RenderTransform>
                <CompositeTransform ScaleY="-1"/>
            </Image.RenderTransform>
        </Image>
        <Image
            Source="/Images/left.png"
            Margin="0,25"
            Stretch="Fill"
            HorizontalAlignment="Left"
            Width="25" />
        <Image
            Source="/Images/left.png"
            Margin="0,25"
            Stretch="Fill"
            HorizontalAlignment="Right"
            Width="25"
            RenderTransformOrigin="0.5,0.5" >
            <Image.RenderTransform>
                <CompositeTransform ScaleX="-1"/>
            </Image.RenderTransform>
        </Image>
        <Image
            Source="/Images/corner.png"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Width="25"
            Height="25" />
        <Image
            Source="/Images/corner.png"
            HorizontalAlignment="Right"
            VerticalAlignment="Top"
            Width="25"
            Height="25"
            RenderTransformOrigin="0.5,0.5" >
            <Image.RenderTransform>
                <CompositeTransform ScaleX="-1"/>
            </Image.RenderTransform>
        </Image>
        <Image
            Source="/Images/corner.png"
            HorizontalAlignment="Left"
            VerticalAlignment="Bottom"
            Width="25"
            Height="25"
            RenderTransformOrigin="0.5,0.5" >
            <Image.RenderTransform>
                <CompositeTransform ScaleY="-1"/>
            </Image.RenderTransform>
        </Image>
        <Image
            Source="/Images/corner.png"
            HorizontalAlignment="Right"
            VerticalAlignment="Bottom"
            Width="25"
            Height="25"
            RenderTransformOrigin="0.5,0.5" >
            <Image.RenderTransform>
                <CompositeTransform ScaleY="-1" ScaleX="-1"/>
            </Image.RenderTransform>
        </Image>
        <ContentPresenter
            x:Name="contentPresenter"
            Margin="25,25,25,25"
            Width="Auto"
            Height="Auto" />
    </Grid>
    

    【讨论】:

    • 赞成,但不是答案 :) 这种方法的问题是它会延长非角图像(左、上、右),因此您不必重复纹理,而是将其拉伸到所需的大小。如果您有兴趣,我可以发布我在此期间找到的解决方案,但它很大(我最终创建了自己的面板)。
    • 带有着色器效果?并在每次区域改变大小时更新效果?
    • 我已经看到使用像素着色器的解决方案,但我试图远离它(不确定手机是否会有 GPU 加速)。我已经更新了这个问题,让你知道我做了什么。
    猜你喜欢
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多