素敵な境界線とコンテンツプレゼンターの内側を持つ汎用コントロールを作成したいと思います(これは左上隅になります)
タイル化された画像ブラシがないという事実を考慮して、これが私が選択した方法です。タイルを事前定義しました (アプリケーションのすべてのシナリオで 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>