如何在wpf中创建多色分段进度条?

时间:2015-11-13 06:43:19

标签: c# wpf xaml progress-bar custom-controls

我尝试创建一个UserControl,作为一种分段进度条。输入将是对象的集合,每个对象将具有类别,持续时间属性和状态属性。 UserControl应该拉伸父控件的宽度和高度。集合中的每个项目应代表进度条的一部分;段的颜色与状态有关,段的宽度与持续时间有关,段上的文本将与类别或其他内容相关。

实施例: Custom Progress Bar

文本可能是集合项的ID,顶部颜色与状态相关,底部颜色与类别相关,宽度与持续时间相关。

我考虑过的一些选项:

  • 制作一个stackpanel并以某种方式定义每个项目的宽度,并将整个事物包装在一个视图框中,以使其拉伸高度和宽度。我如何控制文本大小,如何使内容适合高度,如何将堆栈面板绑定到集合?
  • 为网格控件创建附加属性,该属性将动态创建列并将集合项映射到网格。看起来好像很多工作,我希望这是一个更简单的解决方案,因为我的要求非常具体。
  • 也许这是一种覆盖统一网格以使其不均匀的方法吗?
  • 也许我应该通过迭代我的收藏来全部代码隐藏并绘制矩形?

无论哪种方式,我都在指责有人可能知道解决问题的简单方法。

1 个答案:

答案 0 :(得分:7)

以下是自定义进度条的完整解决方案。

代码在这里:http://1drv.ms/1QmAVuZ

a customized progress bar

1。如果所有步骤的宽度不同,我更喜欢使用带有列和不同宽度的网格

根据以下类动态构建列:

public class StepItem
{
    public int Length { get; set; }
    public int Index { get; set; }
    public String  Label { get; set; }
    public Brush Brush { get; set; }
}

<强> 2。我选择实现CustomControl并继承ItemsControl

CustomControl,因为我不想处理Progressbar模板部分的实现。

ItemsControl因为:

- 我想向ItemsSource属性提供StepItems

的集合

- ItemsControl可以有一些DataTemplate作为每个项目的模板

- ItemsControl可以有PanelGrid作为展示商品集合的模板

第3。该组件在Generic.xaml中有模板

-layoutGrid会有“连续彩虹”

-overlayGrid将部分显示在步骤上,具体取决于进展或完全结束(如果没有进展)

- ItemsPresenter将显示与DataTemplates

相对应的StepItem集合
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type local:ProgressItemsControl}">
            <Border BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">
                <Grid x:Name="layoutGrid">
                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <Grid x:Name="overlayGrid" Width="100" HorizontalAlignment="Right" Background="White"/>
                </Grid>
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>

<强> 4。自定义ItemsPanel以使用网格(而不是垂直布局)

<Setter Property="ItemsPanel">
    <Setter.Value>
        <ItemsPanelTemplate >
            <Grid x:Name="stepsGrid" IsItemsHost="True" />
        </ItemsPanelTemplate>
    </Setter.Value>
</Setter>

<强> 5。在组件后面的代码中,设置列宽

int i = 0;
foreach (StepItem stepItem in ItemsSource)
{
    total += stepItem.Length;
    var columnDefinition = new ColumnDefinition() { Width = new GridLength(stepItem.Length, GridUnitType.Star) };
    stepsGrid.ColumnDefinitions.Add(columnDefinition);
    Grid.SetColumn(stepsGrid.Children[i], stepItem.Index);
    i++;
}

<强> 6。用于声明可以监视的依赖项属性的代码

(节选)

public int Value
{
    get { return (int)GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }
}
// Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueProperty =
    DependencyProperty.Register("Value", typeof(int), typeof(ProgressItemsControl), new PropertyMetadata(0));

<强> 7。组件的使用

<local:CustomProgressBar
    x:Name="customProgressBar1"
    HorizontalAlignment="Left" Height="50" Margin="32,49,0,0"      
    VerticalAlignment="Top" Width="379"/>

<强> 8。使用数据提供组件

private List<StepItem> stepItems = new List<StepItem>{
            new StepItem{
                Index=0,
                Label="Step1",
                Length=20,
                Brush = new SolidColorBrush(Color.FromArgb(255,255,0,0)),
            new StepItem{
                Index=4,
                Label="Step5",
                Length=25,
                Brush = new SolidColorBrush(Color.FromArgb(255,0,128,0)),
           },
        };
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    progressItemsControl1.ItemsSource = stepItems;
}

此致