Frage

Wir schaffen eine XBAP-Anwendung, die wir abgerundete Ecken an verschiedenen Orten auf einer einzigen Seite haben brauchen, und wir möchten einen WPF Rund Eck Container haben eine Reihe von anderen Elementen innerhalb zu platzieren. Hat jemand einige Vorschläge oder Beispielcode haben, wie wir dies am besten erreichen kann? Entweder mit Stilen auf einem oder mit einer benutzerdefinierten Steuerelement erstellen?

War es hilfreich?

Lösung

Sie brauchen nicht eine individuelle Steuerung, nur setzen Sie Ihre Behälter in einem Randelement:

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

Sie können die <Grid/> mit einem des Layout-Container ersetzen ...

Andere Tipps

Ich weiß, dass dies auf die erste Frage ist keine Antwort ... aber Sie wollen oft den inneren Inhalt der abgerundeten Ecke Grenze befestigen Sie gerade erstellt haben.

Chris Cavanagh hat mit einem hervorragende Möglichkeit tun genau dies.

Ich habe ein paar verschiedene Ansätze, um diese versucht ... und ich denke, das ist eine Felsen.

Hier ist die XAML unten:

<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>

Ich hatte gerade dies selbst zu tun, so dachte ich, ich hier eine andere Antwort schreiben würde.

Hier ist eine andere Art und Weise eine abgerundete Ecke Grenze zu erstellen und Clip seinen inneren Gehalt . Dies ist die einfache Art und Weise durch die Clip-Eigenschaft verwenden. Es ist schön, wenn Sie einen VisualBrush vermeiden wollen.

Die 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>

Der Code für den Konverter:

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 Code basierte Implementierung von kobusb Border Control-Lösung. Ich benutzte es, eine List von Button-Steuerelemente zu füllen. Der Button-Steuerelemente wird von MEF-Erweiterungen erstellt. Jede Erweiterung verwendet MEFs ExportMetaData Attribut für eine Beschreibung der Erweiterung. Die Erweiterungen werden Charting Visifire Objekte. Der Benutzer drückt einen Knopf, aus der Liste der Tasten ausgewählt, um die gewünschten Diagramm auszuführen.

        ' 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

Wenn Sie versuchen, einen Knopf zu setzen in einem abgerundeten Rechteck Grenze, sollten Sie überprüfen Msdn Vorbild . Ich fand dies für Bilder des Problems googeln (anstelle von Text). Ihr sperriges äußerte Rechteck ist (zum Glück) leicht zu entfernen.

Beachten Sie, dass Sie auf die Schaltfläche des Verhaltens muss neu definiert werden (da Sie die Control geändert haben). Das heißt, müssen Sie auf die Schaltfläche des Verhalten definieren, wenn mit einem Trigger-Tag angeklickt (Property = „IsPressed“ value = „true“) im ControlTemplate.Triggers-Tag. Hoffe, das spart jemand anderes die Zeit, die ich verloren:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top