125

1 つのページのさまざまな場所に角を丸くする必要がある XBAP アプリケーションを作成しています。WPF Rounded Corner コンテナーを使用して、他の要素を多数配置したいと考えています。これをどのように達成するのが最善かについて、提案やサンプルコードを持っている人はいますか? スタイルを使用するか、カスタム コントロールを作成しますか?

4

5 に答える 5

284

カスタム コントロールは必要ありません。コンテナーを境界要素に配置するだけです。

<Border BorderBrush="#FF000000" BorderThickness="1" CornerRadius="8">
   <Grid/>
</Border>

<Grid/>を任意のレイアウト コンテナーに置き換えることができます...

于 2008-09-23T13:13:11.043 に答える
57

これが最初の質問に対する答えではないことはわかっています...しかし、作成したばかりの角の丸い境界線の内側のコンテンツをクリップしたいことがよくあります。

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>
于 2008-10-16T19:36:21.757 に答える
18

私は自分でこれをしなければならなかったので、ここに別の回答を投稿すると思いました。

角の丸いボーダーを作成し、その内側のコンテンツを切り取る別の方法を次に示します。これは、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();
    }
}
于 2011-08-04T16:56:24.580 に答える
2

kobusb のボーダー コントロール ソリューションの VB.Net コード ベースの実装。これを使用して、ボタン コントロールの ListBox を作成しました。Button コントロールは、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
于 2012-08-22T18:27:49.557 に答える
1

ボタンを角丸長方形の境界線に配置しようとしている場合は、msdn の例を確認してください。問題の画像(テキストではなく)をグーグルで検索して、これを見つけました。かさばる外側の長方形は (ありがたいことに) 簡単に取り外すことができます。

ボタンの動作を再定義する必要があることに注意してください (ControlTemplate を変更したため)。つまり、ControlTemplate.Triggers タグで Trigger タグ (Property="IsPressed" Value="true") を使用してクリックしたときのボタンの動作を定義する必要があります。これが私が失った時間を他の誰かに救うことを願っています:)

于 2010-05-05T20:07:51.877 に答える