如何根据数值调整WPF Toolkit柱状图的柱体颜色与行高
解决方案
1. 重构数据模型
替换原有的KeyValuePair为自定义数据类,拆分标准工时与超出工时,方便后续绑定逻辑:
public class WorkHourItem : INotifyPropertyChanged { private DateTime _date; private int _totalHours; private int _standardHours = 8; // 可根据实际需求调整标准工时 public DateTime Date { get => _date; set { _date = value; OnPropertyChanged(); } } public int TotalHours { get => _totalHours; set { _totalHours = value; OnPropertyChanged(); OnPropertyChanged(nameof(OverHours)); OnPropertyChanged(nameof(StandardHoursUsed)); } } public int StandardHours { get => _standardHours; set { _standardHours = value; OnPropertyChanged(); OnPropertyChanged(nameof(OverHours)); OnPropertyChanged(nameof(StandardHoursUsed)); } } // 计算超出工时(小于0时取0) public int OverHours => Math.Max(0, TotalHours - StandardHours); // 计算标准内工时(大于标准工时取标准值) public int StandardHoursUsed => Math.Min(TotalHours, StandardHours); public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 更新ViewModel
将集合替换为自定义数据类的ObservableCollection,适配新的数据模型:
private ObservableCollection<WorkHourItem> _myGraph; public ObservableCollection<WorkHourItem> MyGraph { get => _myGraph; set { _myGraph = value; OnPropertyChanged(); } } public ChartVM() { MyGraph = new ObservableCollection<WorkHourItem>() { new WorkHourItem { Date = DateTime.Now, TotalHours = 8 }, new WorkHourItem { Date = DateTime.Now.AddDays(1), TotalHours = 11 }, new WorkHourItem { Date = DateTime.Now.AddDays(2), TotalHours = 7 }, new WorkHourItem { Date = DateTime.Now.AddDays(3), TotalHours = 14 }, new WorkHourItem { Date = DateTime.Now.AddDays(4), TotalHours = 5 }, }; }
3. 创建值转换器
需要两个转换器实现动态逻辑:
工时转行高转换器
将工时占总工时的比例转为Grid的Star行高:
public class HourToRowHeightConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is int hours && parameter is int totalHours && totalHours > 0) { double ratio = (double)hours / totalHours; return new GridLength(ratio, GridUnitType.Star); } return GridLength.Auto; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
数值转可见性转换器
控制橙色超出部分的显示/隐藏(无超时则隐藏):
public class HourToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value is int hours && hours > 0 ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
4. 修改XAML代码
在资源中引用转换器,更新ColumnSeries的DataPoint模板,实现动态行高和颜色显示:
<Window.Resources> <local:HourToRowHeightConverter x:Key="HourToRowHeightConverter"/> <local:HourToVisibilityConverter x:Key="HourToVisibilityConverter"/> </Window.Resources> <chartingToolkit:Chart Name="chart1" Title="Availability" VerticalAlignment="Stretch"> <chartingToolkit:Chart.Series> <chartingToolkit:ColumnSeries ItemsSource="{Binding MyGraph}" IndependentValuePath="Date" DependentValuePath="TotalHours"> <chartingToolkit:ColumnSeries.DataPointStyle> <Style TargetType="chartingToolkit:ColumnDataPoint"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="chartingToolkit:ColumnDataPoint"> <Grid> <Grid.RowDefinitions> <!-- 绑定超出工时的比例作为行高 --> <RowDefinition Height="{Binding OverHours, Converter={StaticResource HourToRowHeightConverter}, ConverterParameter={Binding TotalHours}}"/> <!-- 绑定标准内工时的比例作为行高 --> <RowDefinition Height="{Binding StandardHoursUsed, Converter={StaticResource HourToRowHeightConverter}, ConverterParameter={Binding TotalHours}}"/> </Grid.RowDefinitions> <!-- 超出部分:有超时才显示 --> <Rectangle Fill="Orange" Stroke="Black" Visibility="{Binding OverHours, Converter={StaticResource HourToVisibilityConverter}}"/> <!-- 标准内部分 --> <Rectangle Fill="Green" Grid.Row="1"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </chartingToolkit:ColumnSeries.DataPointStyle> </chartingToolkit:ColumnSeries> </chartingToolkit:Chart.Series> </chartingToolkit:Chart>
核心逻辑说明
- 数据模型拆分标准/超出工时,明确各部分数值;
- 行高转换器根据工时占比动态分配Grid两行高度,实现柱体颜色区域的比例适配;
- 可见性转换器确保无超时的柱体不显示橙色区域;
ColumnSeries绑定总工时,保证柱体整体高度与实际工时匹配。
内容的提问来源于stack exchange,提问作者Gokhan
相关产品推荐
相关产品推荐

