首页 文章

如何创建WPF圆角容器?

提问于
浏览
103

我们正在创建一个XBAP应用程序,我们需要在单个页面中的不同位置具有圆角,并且我们希望有一个WPF Rounded Corner容器来放置一堆其他元素 . 有没有人对我们如何才能最好地完成这项工作有一些建议或示例代码?使用样式或创建自定义控件?

5 回答

  • 49

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

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

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

  • 13

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

    克里斯卡瓦纳已经想出了一个excellent way来做到这一点 .

    我尝试了几种不同的方法......我觉得这个方法很震撼 .

    这是下面的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>
    
  • 2

    我必须自己这样做,所以我想我会在这里发布另一个答案 .

    这是另一种创建圆角边框并剪切其内部内容的方法 . 这是使用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();
        }
    }
    
  • 1

    基于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
    
  • 237

    如果您尝试将按钮放在圆角矩形边框中,则应该查看msdn's example . 我通过谷歌搜索问题的图像(而不是文本)找到了这个 . 它们庞大的外部矩形(幸运的是)易于移除 .

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

相关问题