如何创建 WPF 圆角容器?

我们正在创建一个 XBAP 应用程序,我们需要在一个单独的页面中的不同位置有圆角,我们希望有一个 WPF 圆角容器来放置一堆其他元素。是否有人有一些建议或示例代码,我们如何才能最好地完成这一点?是使用 a 上的样式还是使用创建自定义控件?

205999 次浏览

您不需要自定义控件,只需将您的容器放在边框元素中:

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

您可以用任何布局容器替换 <Grid/>..。

我知道这不是最初问题的答案... ... 但是你经常想剪辑刚刚创建的圆角边框的内部内容。

Chris Cavanagh 想出了一个 太棒了来做这个。

我尝试了几种不同的方法,我觉得这个很棒。

下面是一个例子:

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

如果你想把一个按钮放在一个圆角矩形的边框里,你应该看看 Msdn 的例子。我通过搜索问题的图片(而不是文本)发现了这一点。他们笨重的外部矩形是(谢天谢地)容易删除。

注意,您必须重新定义按钮的行为(因为您已经更改了 ControlTemplate)。也就是说,在 ControlTemplate 中使用 Trigger 标记(Property = “ IsPress”Value = “ true”)单击时,需要定义按钮的行为。触发标签。希望这节省了别人我失去的时间:)

我只能自己来,所以我想在这里贴另一个答案。

下面是另一种创建圆角边框 剪辑它的内容的方法。这是使用 Clip 属性的简单方法。如果你不想用 VisualBrush 的话,这很好。

返回文章页面

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