Wie erstelle ich einen WPF-Rund Eck Container?
-
02-07-2019 - |
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?
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:)