単一のページのさまざまな場所に角を丸くする必要があるXBAPアプリケーションを作成しています。WPFの丸みを帯びたコーナーコンテナーに他の要素の束を配置したいと考えています。私たちがこれを最もうまく達成する方法について誰かが提案やサンプルコードを持っていますか?のスタイルまたはカスタムコントロールの作成のどちらか?
単一のページのさまざまな場所に角を丸くする必要があるXBAPアプリケーションを作成しています。WPFの丸みを帯びたコーナーコンテナーに他の要素の束を配置したいと考えています。私たちがこれを最もうまく達成する方法について誰かが提案やサンプルコードを持っていますか?のスタイルまたはカスタムコントロールの作成のどちらか?
回答:
カスタムコントロールは必要ありません。コンテナーを境界要素に配置するだけです。
<Border BorderBrush="#FF000000" BorderThickness="1" CornerRadius="8">
<Grid/>
</Border>
<Grid/>
を任意のレイアウトコンテナーに置き換えることができます...
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="8">
これに適した代替品であり、もう少し簡潔です
これは最初の質問に対する答えではないことはわかっていますが、作成した丸い角のボーダーの内側のコンテンツをクリップしたい場合がよくあります。
Chris Cavanaghは、これを行うための優れた方法を考え出しました。
私はこれにいくつかの異なるアプローチを試みました...そして私はこれが素晴らしいと思います。
以下は、xamlです。
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Black"
>
<!-- Rounded yellow border -->
<Border
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderBrush="Yellow"
BorderThickness="3"
CornerRadius="10"
Padding="2"
>
<Grid>
<!-- Rounded mask (stretches to fill Grid) -->
<Border
Name="mask"
Background="White"
CornerRadius="7"
/>
<!-- Main content container -->
<StackPanel>
<!-- Use a VisualBrush of 'mask' as the opacity mask -->
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=mask}"/>
</StackPanel.OpacityMask>
<!-- Any content -->
<Image Source="http://chriscavanagh.files.wordpress.com/2006/12/chriss-blog-banner.jpg"/>
<Rectangle
Height="50"
Fill="Red"/>
<Rectangle
Height="50"
Fill="White"/>
<Rectangle
Height="50"
Fill="Blue"/>
</StackPanel>
</Grid>
</Border>
</Page>
私は自分でこれをしなければならなかったので、私はここに別の答えを投稿すると思いました。
丸みを帯びたコーナーのボーダーを作成し、その内部コンテンツをクリップする別の方法を次に示します。これは、Clipプロパティを使用する簡単な方法です。VisualBrushを回避したい場合に便利です。
XAML:
<Border
Width="200"
Height="25"
CornerRadius="11"
Background="#FF919194"
>
<Border.Clip>
<RectangleGeometry
RadiusX="{Binding CornerRadius.TopLeft, RelativeSource={RelativeSource AncestorType={x:Type Border}}}"
RadiusY="{Binding RadiusX, RelativeSource={RelativeSource Self}}"
>
<RectangleGeometry.Rect>
<MultiBinding
Converter="{StaticResource widthAndHeightToRectConverter}"
>
<Binding
Path="ActualWidth"
RelativeSource="{RelativeSource AncestorType={x:Type Border}}"
/>
<Binding
Path="ActualHeight"
RelativeSource="{RelativeSource AncestorType={x:Type Border}}"
/>
</MultiBinding>
</RectangleGeometry.Rect>
</RectangleGeometry>
</Border.Clip>
<Rectangle
Width="100"
Height="100"
Fill="Blue"
HorizontalAlignment="Left"
VerticalAlignment="Center"
/>
</Border>
コンバーターのコード:
public class WidthAndHeightToRectConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
double width = (double)values[0];
double height = (double)values[1];
return new Rect(0, 0, width, height);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
VB.Netコードベースのkobusbのボーダーコントロールソリューションの実装。これを使用して、ButtonコントロールのListBoxを作成しました。ボタンコントロールはMEF拡張機能から作成されます。各拡張機能は、拡張機能の説明にMEFのExportMetaData属性を使用します。拡張機能はVisiFireチャートオブジェクトです。ユーザーは、ボタンのリストから選択されたボタンを押して、目的のチャートを実行します。
' Create a ListBox of Buttons, one button for each MEF charting component.
For Each c As Lazy(Of ICharts, IDictionary(Of String, Object)) In ext.ChartDescriptions
Dim brdr As New Border
brdr.BorderBrush = Brushes.Black
brdr.BorderThickness = New Thickness(2, 2, 2, 2)
brdr.CornerRadius = New CornerRadius(8, 8, 8, 8)
Dim btn As New Button
AddHandler btn.Click, AddressOf GenericButtonClick
brdr.Child = btn
brdr.Background = btn.Background
btn.Margin = brdr.BorderThickness
btn.Width = ChartsLBx.ActualWidth - 22
btn.BorderThickness = New Thickness(0, 0, 0, 0)
btn.Height = 22
btn.Content = c.Metadata("Description")
btn.Tag = c
btn.ToolTip = "Push button to see " & c.Metadata("Description").ToString & " chart"
Dim lbi As New ListBoxItem
lbi.Content = brdr
ChartsLBx.Items.Add(lbi)
Next
Public Event Click As RoutedEventHandler
Private Sub GenericButtonClick(sender As Object, e As RoutedEventArgs)
Dim btn As Button = DirectCast(sender, Button)
Dim c As Lazy(Of ICharts, IDictionary(Of String, Object)) = DirectCast(btn.Tag, Lazy(Of ICharts, IDictionary(Of String, Object)))
Dim w As Window = DirectCast(c.Value, Window)
Dim cc As ICharts = DirectCast(c.Value, ICharts)
c.Value.CreateChart()
w.Show()
End Sub
<System.ComponentModel.Composition.Export(GetType(ICharts))> _
<System.ComponentModel.Composition.ExportMetadata("Description", "Data vs. Time")> _
Public Class DataTimeChart
Implements ICharts
Public Sub CreateChart() Implements ICharts.CreateChart
End Sub
End Class
Public Interface ICharts
Sub CreateChart()
End Interface
Public Class Extensibility
Public Sub New()
Dim catalog As New AggregateCatalog()
catalog.Catalogs.Add(New AssemblyCatalog(GetType(Extensibility).Assembly))
'Create the CompositionContainer with the parts in the catalog
ChartContainer = New CompositionContainer(catalog)
Try
ChartContainer.ComposeParts(Me)
Catch ex As Exception
Console.WriteLine(ex.ToString)
End Try
End Sub
' must use Lazy otherwise instantiation of Window will hold open app. Otherwise must specify Shutdown Mode of "Shutdown on Main Window".
<ImportMany()> _
Public Property ChartDescriptions As IEnumerable(Of Lazy(Of ICharts, IDictionary(Of String, Object)))
End Class
丸みを帯びた長方形の境界線にボタンを配置する場合は、msdnの例を確認してください。これは、問題の画像(テキストではなく)をグーグル検索して見つけました。かさばる外側の長方形は(ありがたいことに)簡単に削除できます。
ボタンの動作を再定義する必要があることに注意してください(ControlTemplateを変更したため)。つまり、ControlTemplate.TriggersタグのTriggerタグ(Property = "IsPressed" Value = "true")を使用してクリックしたときのボタンの動作を定義する必要があります。これが私が失った時間を他の誰かが救うことを願っています:)