wpf - 在 WPF 中实现向导进度控制

标签 wpf xaml

有没有最好的方法在 WPF 中实现这样的控件?

Wizard Progress Control

我可以轻松复制文本标签和进度条(没有每个标签上方的圆形“凸起”),但我想知道是否已经有一个控件,或者最佳实践,用于在 WPF 中创建此类控件.

最佳答案

很难说在这种情况下最佳做法是什么,但这是我的做法。

屏幕截图中的向导控件看起来像是 ProgressBar 的组合。和一个 ItemsControl在这种情况下,我似乎更容易从 ItemsControl 推导出来并实现进度功能而不是其他方式,但这也取决于您希望它如何工作(例如,如果您想要平稳的进度或只是一个一个地点亮点)。

使用 UniformGridItemsPanelItemTemplate下面,我们得到以下外观(步骤是 List 的字符串)
enter image description here

<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>

添加 DropShadowEffectItemsPanel , 二 Path元素到 ItemTemplate和两个 DataTriggers确定当前项目是显示/隐藏左/右的第一个还是最后一个项目Path我们可以获得与您的屏幕截图非常相似的外观
enter image description here

项目面板
<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

    看起来像这样
    enter image description here

    sample 注意事项
  • 我最终遇到了我会得到 DropShadowEffect 的情况。在进度部分和标题上,或者在每个项目之间画一条细线(如图所示)。我想不出一个简单的方法来摆脱它,所以也许这毕竟不是最好的方法:)
  • 进度部分很简单。它只有一个 0-100 之间的值,然后转换器决定该项目是否应该被点亮
  • 此控件可能会对性能产生很小的影响,但我无法确定,因为我的计算机今天似乎运行得很慢...

  • 更新

    对示例项目进行了一些更改,我将演示文稿分成两部分 ItemsControls摆脱每个项目之间的细线。现在看起来像这样
    enter image description here
    上传到这里: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/

    相关文章:

    用户控件内的 wpf 弹出窗口,按钮不响应事件或命令

    c# - WPF C# - 更改菜单背景的画笔

    wpf - 当 DataGrid 接收到键盘焦点时,关注 SelectedItem 的 DataGridCell

    wpf - 我该如何让那个该死的 wpf 弹出窗口消失?

    c# - Image Control 不显示使用 OpenCVsharp 捕获的网络摄像头帧

    c# - 如何在 WPF 中显示按钮被单击(按下)?

    c# - "The subprocess making the call can not access this object because the owner is another thread"异常异步/等待 WPF C#

    c# - 如何通过正则表达式屏蔽输入? 1112223333 或 1112223333444

    c# - Windows 8 需要创建向导自定义控件

    c# - 过滤使用嵌套的 xaml 数据模板显示的分层对象