我有一个ListViewItem,我应用了一个Style,我想把一个灰色虚线作为底部Border。在WPF中我怎么做呢?我只能看到纯色画笔。
ListViewItem
Style
Border
8mmmxcuj1#
这在我们的应用程序中效果很好,允许我们使用真实的的边框,而不是在矩形上乱花:
<Border BorderThickness="1,0,1,1"> <Border.BorderBrush> <DrawingBrush Viewport="0,0,8,8" ViewportUnits="Absolute" TileMode="Tile"> <DrawingBrush.Drawing> <DrawingGroup> <GeometryDrawing Brush="Black"> <GeometryDrawing.Geometry> <GeometryGroup> <RectangleGeometry Rect="0,0,50,50" /> <RectangleGeometry Rect="50,50,50,50" /> </GeometryGroup> </GeometryDrawing.Geometry> </GeometryDrawing> </DrawingGroup> </DrawingBrush.Drawing> </DrawingBrush> </Border.BorderBrush> <TextBlock Text="Content Goes Here!" Margin="5"/> </Border>
请注意,Viewport决定线条中虚线的大小。在本例中,它生成8像素的虚线。Viewport=“0,0,4,4”将给予4像素的虚线。
pokxtpni2#
您可以创建一个虚线或破折号线使用矩形一样,在下面的代码
<Rectangle Stroke="#FF000000" Height="1" StrokeThickness="1" StrokeDashArray="4 4" SnapsToDevicePixels="True"/>
从这里开始,并根据您的场景自定义您的ListView
lxkprmvk3#
有点晚了,但下面的解决方案对我很有效。它比其他两个解决方案稍微简单/更好:
<Border BorderThickness="1"> <Border.BorderBrush> <VisualBrush> <VisualBrush.Visual> <Rectangle StrokeDashArray="4 2" Stroke="Gray" StrokeThickness="1" Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualWidth}" Height="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualHeight}"/> </VisualBrush.Visual> </VisualBrush> </Border.BorderBrush> <TextBlock Text="Whatever" /> </Border>
1qczuiv04#
克默尔
<Grid> <Grid.RowDefinitions><RowDefinition Height="auto"/></Grid.RowDefinitions> <Grid.ColumnDefinitions><ColumnDefinition Width="auto"/></Grid.ColumnDefinitions> <Rectangle RadiusX="9" RadiusY="9" Fill="White" Stroke="Black" StrokeDashArray="1,2"/> <TextBlock Padding = "4,2" Text="Whatever"/> </Grid>
ikfrs5lh5#
我们的团队最近将此作为一个需求,我们通过创建一个自定义控件DashedBorder来解决它,该控件扩展了Border并添加了虚线边框功能。它具有3个新的依赖项属性
DashedBorder
UseDashedBorder
DashedBorderBrush
StrokeDashArray
像这样使用
<controls:DashedBorder UseDashedBorder="True" DashedBorderBrush="#878787" StrokeDashArray="2 1" Background="#EBEBEB" BorderThickness="3" CornerRadius="10 10 10 10"> <TextBlock Text="Dashed Border" Margin="6 2 6 2"/> </controls:DashedBorder>
并生成如下结果
当UseDashedBorder被设置为true时,它将创建一个带有2个矩形的VisualBrush,并将其设置为BorderBrush(这就是为什么我们需要为实际BorderBrush的颜色添加一个额外的属性)。第一个属性是创建虚线,第二个属性是用边框的Background填充空白。它将Rectangle虚线属性Map到DashedBorder属性,如下所示
true
VisualBrush
BorderBrush
Background
Rectangle
Stroke
StrokeThickness
BorderThickness.Left
RadiusX
CornerRadius.TopLeft
RadiusY
Width
ActualWidth
Height
ActualHeight
public class DashedBorder : Border { private static DoubleCollection? emptyDoubleCollection; private static DoubleCollection EmptyDoubleCollection() { if (emptyDoubleCollection == null) { DoubleCollection doubleCollection = new DoubleCollection(); doubleCollection.Freeze(); emptyDoubleCollection = doubleCollection; } return emptyDoubleCollection; } public static readonly DependencyProperty UseDashedBorderProperty = DependencyProperty.Register(nameof(UseDashedBorder), typeof(bool), typeof(DashedBorder), new FrameworkPropertyMetadata(false, OnUseDashedBorderChanged)); public static readonly DependencyProperty DashedBorderBrushProperty = DependencyProperty.Register(nameof(DashedBorderBrush), typeof(Brush), typeof(DashedBorder), new FrameworkPropertyMetadata(null)); public static readonly DependencyProperty StrokeDashArrayProperty = DependencyProperty.Register(nameof(StrokeDashArray), typeof(DoubleCollection), typeof(DashedBorder), new FrameworkPropertyMetadata(EmptyDoubleCollection())); private static void OnUseDashedBorderChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) { DashedBorder dashedBorder = (DashedBorder)target; dashedBorder.UseDashedBorderChanged(); } private Rectangle GetBoundRectangle() { Rectangle rectangle = new Rectangle(); rectangle.SetBinding(Rectangle.StrokeThicknessProperty, new Binding() { Source = this, Path = new PropertyPath("BorderThickness.Left") }); rectangle.SetBinding(Rectangle.RadiusXProperty, new Binding() { Source = this, Path = new PropertyPath("CornerRadius.TopLeft") }); rectangle.SetBinding(Rectangle.RadiusYProperty, new Binding() { Source = this, Path = new PropertyPath("CornerRadius.TopLeft") }); rectangle.SetBinding(Rectangle.WidthProperty, new Binding() { Source = this, Path = new PropertyPath(ActualWidthProperty) }); rectangle.SetBinding(Rectangle.HeightProperty, new Binding() { Source = this, Path = new PropertyPath(ActualHeightProperty) }); return rectangle; } private Rectangle GetBackgroundRectangle() { Rectangle rectangle = GetBoundRectangle(); rectangle.SetBinding(Rectangle.StrokeProperty, new Binding() { Source = this, Path = new PropertyPath(BackgroundProperty) }); return rectangle; } private Rectangle GetDashedRectangle() { Rectangle rectangle = GetBoundRectangle(); rectangle.SetBinding(Rectangle.StrokeDashArrayProperty, new Binding() { Source = this, Path = new PropertyPath(StrokeDashArrayProperty) }); rectangle.SetBinding(Rectangle.StrokeProperty, new Binding() { Source = this, Path = new PropertyPath(DashedBorderBrushProperty) }); Panel.SetZIndex(rectangle, 2); return rectangle; } private VisualBrush CreateDashedBorderBrush() { VisualBrush dashedBorderBrush = new VisualBrush(); Grid grid = new Grid(); Rectangle backgroundRectangle = GetBackgroundRectangle(); Rectangle dashedRectangle = GetDashedRectangle(); grid.Children.Add(backgroundRectangle); grid.Children.Add(dashedRectangle); dashedBorderBrush.Visual = grid; return dashedBorderBrush; } private void UseDashedBorderChanged() { if (UseDashedBorder) { BorderBrush = CreateDashedBorderBrush(); } else { ClearValue(BorderBrushProperty); } } public bool UseDashedBorder { get { return (bool)GetValue(UseDashedBorderProperty); } set { SetValue(UseDashedBorderProperty, value); } } public Brush DashedBorderBrush { get { return (Brush)GetValue(DashedBorderBrushProperty); } set { SetValue(DashedBorderBrushProperty, value); } } public DoubleCollection StrokeDashArray { get { return (DoubleCollection)GetValue(StrokeDashArrayProperty); } set { SetValue(StrokeDashArrayProperty, value); } } }
67up9zun6#
我正在做一个用户控件....我一直在尝试一个行军蚂蚁边框的故事板。基本的矩形和文本网格工作得很好,因为没有交互。当试图在网格内放置一个按钮时,矩形或按钮都是可见的,但它们都不可见。另一篇文章:Advanced XAML Animation effects. Pulse, Marching ants, Rotations. Alerts使用dotNet的VisualBrush解决方案,将矩形移动到边框上,并在边框内添加一个按钮,效果非常好。
<UserControl.Resources> <ResourceDictionary> <Style TargetType="{x:Type TextBlock}" x:Key="LOC_DG_Cell_Mid" BasedOn="{StaticResource DG_TextBlock_Mid}" > <Setter Property="Margin" Value="5 0"/> </Style> <Storyboard x:Key="MarchingAnts"> <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="AlertBox" Storyboard.TargetProperty="StrokeThickness" To="4" Duration="0:0:0.25" /> <!-- If you want to run counter-clockwise, just swap the 'From' and 'To' values. --> <DoubleAnimation BeginTime="00:00:00" RepeatBehavior="Forever" Storyboard.TargetName="AlertBox" Storyboard.TargetProperty="StrokeDashOffset" Duration="0:3:0" From="1000" To="0"/> </Storyboard> </ResourceDictionary> </UserControl.Resources> <UserControl.Triggers> <EventTrigger RoutedEvent="FrameworkElement.Loaded"> <BeginStoryboard Storyboard="{StaticResource MarchingAnts}"/> </EventTrigger> </UserControl.Triggers> <Grid> <Border BorderThickness="1"> <Border.BorderBrush> <VisualBrush> <VisualBrush.Visual> <Rectangle x:Name="AlertBox" Stroke="Red" StrokeDashOffset="2" StrokeDashArray="5" Margin="5" Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualWidth}" Height="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualHeight}"/> </VisualBrush.Visual> </VisualBrush> </Border.BorderBrush> <Button x:Name="FinishedButton" Padding="0 5" Margin="0" Style="{StaticResource IconButton}" > <StackPanel Orientation="Horizontal" > <Label Style="{StaticResource ButtonLabel}" Content="Processing has Finished" /> </StackPanel> </Button> </Border> </Grid>
anauzrmj7#
如果您正在寻找像素完美的虚线
public static class DashBrushFactory { public static Brush CreateBrush(double dpiScale, SolidColorBrush solidColorBrush) { const double dashLength = 4; const double dashSpace = 4; double dashLengthPixelSnapped = SnapToPixel(dashLength, dpiScale); double dashSpacePixelSnapped = SnapToPixel(dashSpace, dpiScale); ImageBrush imageBrush = new ImageBrush(); DrawingImage drawingImage = new DrawingImage(); GeometryDrawing geometryDrawing = new GeometryDrawing(); GeometryGroup geometryGroup = new GeometryGroup(); RectangleGeometry rectangleGeometry1 = new RectangleGeometry(); RectangleGeometry rectangleGeometry2 = new RectangleGeometry(); rectangleGeometry1.Rect = new Rect(0, 0, dashLengthPixelSnapped, dashLengthPixelSnapped); rectangleGeometry2.Rect = new Rect(dashLengthPixelSnapped, dashLengthPixelSnapped, dashSpacePixelSnapped, dashSpacePixelSnapped); rectangleGeometry1.Freeze(); rectangleGeometry2.Freeze(); geometryGroup.Children.Add(rectangleGeometry1); geometryGroup.Children.Add(rectangleGeometry2); geometryGroup.Freeze(); geometryDrawing.Brush = solidColorBrush; geometryDrawing.Geometry = geometryGroup; geometryDrawing.Freeze(); drawingImage.Drawing = geometryDrawing; drawingImage.Freeze(); imageBrush.TileMode = TileMode.Tile; imageBrush.ViewportUnits = BrushMappingMode.Absolute; imageBrush.Viewport = new Rect(0, 0, dashLengthPixelSnapped * 2, dashSpacePixelSnapped * 2); imageBrush.ImageSource = drawingImage; imageBrush.Freeze(); return imageBrush; } private static double SnapToPixel(double value, double dpiScale) { double newValue; // If DPI == 1, don't use DPI-aware rounding. if (DoubleUtil.AreClose(dpiScale, 1.0) == false) { newValue = Math.Round(value * dpiScale) / dpiScale; // If rounding produces a value unacceptable to layout (NaN, Infinity or MaxValue), use the original value. if (DoubleUtil.IsNaN(newValue) || Double.IsInfinity(newValue) || DoubleUtil.AreClose(newValue, Double.MaxValue)) { newValue = value; } } else { newValue = Math.Round(value); } return newValue; } }
https://referencesource.microsoft.com/#WindowsBase/Shared/MS/Internal/DoubleUtil.cs
7条答案
按热度按时间8mmmxcuj1#
这在我们的应用程序中效果很好,允许我们使用真实的的边框,而不是在矩形上乱花:
请注意,Viewport决定线条中虚线的大小。在本例中,它生成8像素的虚线。Viewport=“0,0,4,4”将给予4像素的虚线。
pokxtpni2#
您可以创建一个虚线或破折号线使用矩形一样,在下面的代码
从这里开始,并根据您的场景自定义您的ListView
lxkprmvk3#
有点晚了,但下面的解决方案对我很有效。它比其他两个解决方案稍微简单/更好:
1qczuiv04#
克默尔
ikfrs5lh5#
我们的团队最近将此作为一个需求,我们通过创建一个自定义控件
DashedBorder
来解决它,该控件扩展了Border
并添加了虚线边框功能。它具有3个新的依赖项属性
UseDashedBorder
(布尔值)DashedBorderBrush
(刷子)StrokeDashArray
(DoubleCollection)像这样使用
并生成如下结果
当
UseDashedBorder
被设置为true
时,它将创建一个带有2个矩形的VisualBrush
,并将其设置为BorderBrush
(这就是为什么我们需要为实际BorderBrush
的颜色添加一个额外的属性)。第一个属性是创建虚线,第二个属性是用边框的Background
填充空白。它将
Rectangle
虚线属性Map到DashedBorder
属性,如下所示StrokeDashArray
=〉StrokeDashArray
Stroke
=〉DashedBorderBrush
StrokeThickness
=〉BorderThickness.Left
RadiusX
=〉CornerRadius.TopLeft
RadiusY
=〉CornerRadius.TopLeft
Width
=〉ActualWidth
Height
=〉ActualHeight
虚线边框.cs
67up9zun6#
我正在做一个用户控件....我一直在尝试一个行军蚂蚁边框的故事板。基本的矩形和文本网格工作得很好,因为没有交互。当试图在网格内放置一个按钮时,矩形或按钮都是可见的,但它们都不可见。
另一篇文章:Advanced XAML Animation effects. Pulse, Marching ants, Rotations. Alerts
使用dotNet的VisualBrush解决方案,将矩形移动到边框上,并在边框内添加一个按钮,效果非常好。
anauzrmj7#
如果您正在寻找像素完美的虚线
https://referencesource.microsoft.com/#WindowsBase/Shared/MS/Internal/DoubleUtil.cs