WPF 둥근 코너 컨테이너를 어떻게 생성합니까?
-
02-07-2019 - |
문제
우리는 단일 페이지의 다양한 위치에 모서리를 반올림 해야하는 XBAP 응용 프로그램을 만들고 있으며 WPF 둥근 코너 컨테이너가있어 다른 많은 요소를 배치하고 싶습니다. 누구든지 우리가 이것을 가장 잘 달성 할 수있는 방법에 대한 제안이나 샘플 코드가 있습니까? A의 스타일이 있거나 사용자 정의 컨트롤을 만드는가?
해결책
사용자 정의 컨트롤이 필요하지 않으며 컨테이너를 테두리 요소에 넣으십시오.
<Border BorderBrush="#FF000000" BorderThickness="1" CornerRadius="8">
<Grid/>
</Border>
당신은 그것을 교체 할 수 있습니다 <Grid/>
레이아웃 컨테이너가 있는데 ...
다른 팁
나는 이것이 초기 질문에 대한 답이 아니라는 것을 알고 있습니다. 그러나 당신은 종종 당신이 방금 만든 둥근 코너 테두리의 내부 내용을 클립하고 싶습니다.
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>
방금 직접해야했기 때문에 여기에 또 다른 답변을 게시 할 것이라고 생각했습니다.
둥근 코너 테두리를 만드는 또 다른 방법이 있습니다. 내부 컨텐츠를 자릅니다. 클립 속성을 사용하여 간단한 방법입니다. 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();
}
}
Kobusb의 국경 제어 솔루션의 VB.NET 코드 기반 구현. 버튼 컨트롤의 목록 상자를 채우는 데 사용했습니다. 버튼 컨트롤은 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
둥근 고리 테두리에 버튼을 넣으려면 확인해야합니다. MSDN의 예. 문제의 이미지 (텍스트 대신)에 대한 인터넷 검색으로 이것을 찾았습니다. 그들의 부피가 큰 외부 사각형은 (고맙게도) 제거하기 쉽습니다.
ControlTemplate을 변경했기 때문에 버튼의 동작을 재정의해야합니다. 즉, ControlTemplate.Triggers 태그에서 트리거 태그 (Property = "ispressed"value = "true")를 사용하여 클릭 할 때 버튼의 동작을 정의해야합니다. 이것이 내가 잃어버린 시간을 다른 사람을 구해주기를 바랍니다 :)