如何使用ViewModel中的属性剪切/整形ProgressBar
指示符?
我想使用Slider
向ProgressBar
控件添加反馈指示符,其中我剪辑以便只显示一行圆圈。由于视图可以调整大小并且圆直径是固定的,我想将剪切的形状绑定到一个属性,指示要显示的圆圈数。
我尝试使用VisualBrush
,其中我平铺了Elipse
个形状。但最终是个别圈子被削减,这看起来并不好。
这里的圆圈是我想要达到的目的:
<ProgressBar x:Name="PART_FeedbackBar" Grid.Column="1" Grid.Row="1"
Value="{Binding Path=Value}"
Maximum="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Slider}}, Path=Maximum}"
Minimum="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Slider}}, Path=Minimum}"
Orientation="Horizontal"
BorderThickness="0"
Background="{StaticResource PrimaryColor}"
Foreground="{StaticResource HighlightColor}"
Height="20">
<ProgressBar.Clip>
<!-- What to add here? -->
</ProgressBar.Clip>
</ProgressBar>
答案 0 :(得分:0)
好吧,我找到了使用ProgressBar.OpacityMask
而不是ProgressBar.Clip
的解决方案,因为ProgressBar.OpacityMask
支持VisualBrush
。通过这种方式,我可以平铺Elipse
,其中ProgressBar
Opacity
设置为0。
要将圈数设置为ProgressBar
宽度,我添加了一个SizeChanged
事件处理程序,用于计算Elipse
个形状的数量。 VisualBrush
Viewport
属性绑定到Elipse
计数属性,使用Converter
将int
值转换为Rect
。
结果:
XAML:
<ProgressBar x:Name="PART_FeedbackBar" Grid.Column="1" Grid.Row="1"
SizeChanged="PART_FeedbackBar_SizeChanged"
Value="{Binding Path=Value}"
Maximum="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Slider}}, Path=Maximum}"
Minimum="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Slider}}, Path=Minimum}"
Orientation="Horizontal"
BorderThickness="0"
Foreground="{StaticResource HighlightColor}"
Background="{StaticResource PrimaryColor}"
Height="15"
Margin="25,10">
<ProgressBar.OpacityMask>
<VisualBrush x:Name="FeedbackBarOpacityMask" TileMode="Tile"
Viewport="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type UserControl}}, Path=FeedbackDotCount,
Converter={converters:IntegerToViewportConverter}}"
Stretch="Uniform">
<VisualBrush.Visual>
<Ellipse Height="1" Width="1" Fill="Black" />
</VisualBrush.Visual>
</VisualBrush>
</ProgressBar.OpacityMask>
</ProgressBar>
SizeChanged事件处理程序:
private void PART_FeedbackBar_SizeChanged(object sender, SizeChangedEventArgs e)
{
FeedbackDotCount = (int)Math.Ceiling(e.NewSize.Width / 25);
}
转换器:
public class IntegerToViewportConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var count = (int)value;
var viewport = new Rect(0, 0, 0, 1);
if (count > 0)
{
viewport.Width = 1 / (double)count;
}
return viewport;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}