有没有最好的方法在 WPF 中实现这样的控件?
我可以轻松复制文本标签和进度条(没有每个标签上方的圆形“凸起”),但我想知道是否已经有一个控件,或者最佳实践,用于在 WPF 中创建此类控件.
最佳答案
很难说在这种情况下最佳做法是什么,但这是我的做法。
屏幕截图中的向导控件看起来像是 ProgressBar
的组合。和一个 ItemsControl
在这种情况下,我似乎更容易从 ItemsControl
推导出来并实现进度功能而不是其他方式,但这也取决于您希望它如何工作(例如,如果您想要平稳的进度或只是一个一个地点亮点)。
使用 UniformGrid
如 ItemsPanel
和 ItemTemplate
下面,我们得到以下外观(步骤是 List
的字符串)
<ItemsControl ItemsSource="{Binding Steps}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Ellipse HorizontalAlignment="Center" Height="20" Width="20" Stroke="Transparent" Fill="Blue"/>
<TextBlock Grid.Row="1" Text="{Binding}" HorizontalAlignment="Center" Margin="0,5,0,0"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
添加
DropShadowEffect
到 ItemsPanel
, 二 Path
元素到 ItemTemplate
和两个 DataTriggers
确定当前项目是显示/隐藏左/右的第一个还是最后一个项目Path
我们可以获得与您的屏幕截图非常相似的外观项目面板
<UniformGrid Rows="1" SnapsToDevicePixels="True">
<UniformGrid.Effect>
<DropShadowEffect Color="Black"
BlurRadius="5"
Opacity="0.6"
ShadowDepth="0"/>
</UniformGrid.Effect>
</UniformGrid>
项目模板
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="Path">
<Setter Property="Data" Value="M0.0,0.0 L0.0,0.33 L1.0,0.33 L1.0,0.66 L0.0,0.66 L0.0,1.0"/>
<Setter Property="StrokeThickness" Value="0"/>
<Setter Property="Height" Value="21"/>
<Setter Property="Stretch" Value="Fill"/>
<Setter Property="Fill" Value="{StaticResource wizardBarBrush}"/>
<Setter Property="StrokeEndLineCap" Value="Square"/>
<Setter Property="StrokeStartLineCap" Value="Square"/>
<Setter Property="Stroke" Value="Transparent"/>
</Style>
</DataTemplate.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Path Name="leftPath"/>
<Path Name="rightPath" Grid.Column="1"/>
<Ellipse Grid.ColumnSpan="2" HorizontalAlignment="Center" Height="20" Width="20" Stroke="Transparent" Fill="{StaticResource wizardBarBrush}"/>
<TextBlock Grid.ColumnSpan="2" Grid.Row="1" Text="{Binding}" HorizontalAlignment="Center" Margin="0,5,0,0"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}"
Value="{x:Null}">
<Setter TargetName="leftPath" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={markup:IsLastItemConverter}}"
Value="True">
<Setter TargetName="rightPath" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
如果你决定使用这种方法,你可能会想出如何让剩下的事情继续下去,比如
DropShadowEffect
),而不是在文本 无论如何,我上传了一个带有名为
WizardProgressBar
的自定义控件的示例项目。以及在此处使用它的演示项目:https://www.dropbox.com/s/ng9vfi6uwn1peot/WizardProgressBarDemo2.zip?dl=0看起来像这样
sample 注意事项
DropShadowEffect
的情况。在进度部分和标题上,或者在每个项目之间画一条细线(如图所示)。我想不出一个简单的方法来摆脱它,所以也许这毕竟不是最好的方法:) 更新
对示例项目进行了一些更改,我将演示文稿分成两部分
ItemsControls
摆脱每个项目之间的细线。现在看起来像这样上传到这里:https://www.dropbox.com/s/ng9vfi6uwn1peot/WizardProgressBarDemo2.zip?dl=0
更新结束
这是上面示例代码中缺少的部分
<LinearGradientBrush x:Key="wizardBarBrush" StartPoint="0.5,0.0" EndPoint="0.5,1.0">
<GradientStop Color="#FFE4E4E4" Offset="0.25"/>
<GradientStop Color="#FFededed" Offset="0.50"/>
<GradientStop Color="#FFFCFCFC" Offset="0.75"/>
</LinearGradientBrush>
IsLastItemConverter
public class IsLastItemConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ContentPresenter contentPresenter = value as ContentPresenter;
ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(contentPresenter);
int index = itemsControl.ItemContainerGenerator.IndexFromContainer(contentPresenter);
return (index == (itemsControl.Items.Count - 1));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
public IsLastItemConverter() { }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
关于wpf - 在 WPF 中实现向导进度控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7691386/