如何在 wpf 中制作 multi-colored 分段进度条?
How can I make a multi-colored segmented progress bar in wpf?
我正在尝试创建一个用作分段进度条的 UserControl。输入将是 object 的 collection,每个 object 都有一个类别、持续时间 属性 和状态 属性。 UserControl 应该拉伸 parent 控件的宽度和高度。 collection 中的每一项都应该代表进度条的一段;段的颜色与状态有关,段的宽度与持续时间有关,段上覆盖的文本与类别或其他内容有关。
自定义进度条示例:
文本可能是 collection 项目的 ID,顶部颜色与状态相关,底部颜色与类别相关,宽度与持续时间相关。
我考虑过的一些选项:
- 制作一个堆栈面板并以某种方式定义每个项目的宽度并将整个内容包装在一个视图框中以使其拉伸高度和宽度。如何控制文本大小,如何使内容适合高度,如何将堆栈面板绑定到 collection?
- 为将动态创建列并将 collection 项映射到网格的网格控件创建一个附加的 属性。看起来工作量很大,我希望有一个更简单的解决方案,因为我的要求非常具体。
- 也许有一种方法可以覆盖统一网格以使其成为 non-uniform?
- 也许我应该全部 code-behind 并通过遍历我的 collection 来绘制矩形?
无论如何,我祈祷有人可能知道解决我的问题的简单方法。
这里是自定义进度条的完整解决方案。
代码在这里:http://1drv.ms/1QmAVuZ
1。如果所有台阶的宽度都不一样,我更喜欢使用带列和不同宽度的网格
列是根据以下 class 动态构建的:
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
可以有任何 Panel
像 Grid
作为展示项目集合的模板
3。该组件在 Generic.xaml
中有模板
-layoutGrid 将具有 "continuous rainbow"
-overlayGrid 将根据进度部分显示在步骤上或完全显示(如果没有进度)
-ItemsPresenter
会呈现每个StepItem
对应的DataTemplates
的合集
<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;
}
此致
我正在尝试创建一个用作分段进度条的 UserControl。输入将是 object 的 collection,每个 object 都有一个类别、持续时间 属性 和状态 属性。 UserControl 应该拉伸 parent 控件的宽度和高度。 collection 中的每一项都应该代表进度条的一段;段的颜色与状态有关,段的宽度与持续时间有关,段上覆盖的文本与类别或其他内容有关。
自定义进度条示例:
文本可能是 collection 项目的 ID,顶部颜色与状态相关,底部颜色与类别相关,宽度与持续时间相关。
我考虑过的一些选项:
- 制作一个堆栈面板并以某种方式定义每个项目的宽度并将整个内容包装在一个视图框中以使其拉伸高度和宽度。如何控制文本大小,如何使内容适合高度,如何将堆栈面板绑定到 collection?
- 为将动态创建列并将 collection 项映射到网格的网格控件创建一个附加的 属性。看起来工作量很大,我希望有一个更简单的解决方案,因为我的要求非常具体。
- 也许有一种方法可以覆盖统一网格以使其成为 non-uniform?
- 也许我应该全部 code-behind 并通过遍历我的 collection 来绘制矩形?
无论如何,我祈祷有人可能知道解决我的问题的简单方法。
这里是自定义进度条的完整解决方案。
代码在这里:http://1drv.ms/1QmAVuZ
1。如果所有台阶的宽度都不一样,我更喜欢使用带列和不同宽度的网格
列是根据以下 class 动态构建的:
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
可以有任何 Panel
像 Grid
作为展示项目集合的模板
3。该组件在 Generic.xaml
中有模板-layoutGrid 将具有 "continuous rainbow"
-overlayGrid 将根据进度部分显示在步骤上或完全显示(如果没有进度)
-ItemsPresenter
会呈现每个StepItem
DataTemplates
的合集
<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;
}
此致