You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVVM模式下动态绑定X/Y值到图表遇轴适配错误求助

问题:动态绑定LineSeries时出现"No suitable axis is available"错误

我的UI通过磁贴展示多个数据点,点击磁贴会打开新窗口绘制该字段最近60条数据的时间趋势图。采用MVVM架构,尝试把X轴(SampleTime)和Y值动态绑定到DotNetProjects.DataVisualization.Toolkit的LineSeries时,抛出错误:

System.InvalidOperationException: 'No suitable axis is available for plotting the dependent value.'

ViewModel代码

public partial class MainViewChartVM : ObservableObject
{
    private const int N_RECORDS = 60;

    private DataProperty _currentChartItem;

    public enum DataProperty
    {
        AmbientTemp,
        RelativeHumidity,
        BarometricPressure,
        WindSpeed,
        WindDirection,
    }

    public MainViewChartVM(DataProperty currentChartItem)
    {
        _currentChartItem = currentChartItem;

        InitializeChart();
    }

    [ObservableProperty]
    private string _chartTitle;
    [ObservableProperty]
    private string _chartUnits;
    [ObservableProperty]
    private ObservableCollection<Sample_Data> _currentDataSet;
    [ObservableProperty]
    private string _independentValuePath;
    [ObservableProperty]
    private string _dependentValuePath;

    private void InitializeChart()
    {
        // Update button options

        // Update chart
        CurrentDataSet = new ObservableCollection<Sample_Data>(DataLogger.Instance.ReadLastNSamples(N_RECORDS));

        IndependentValuePath = nameof(Sample_Data.SampleTime);

        switch (_currentChartItem)
        {
            case DataProperty.AmbientTemp:
                ChartTitle = nameof(Sample_Data.AmbientTemp);
                DependentValuePath = nameof(Sample_Data.AmbientTemp);
                break;
            case DataProperty.RelativeHumidity:
                break;
            case DataProperty.BarometricPressure:
                break;
            case DataProperty.WindSpeed:
                break;
            case DataProperty.WindDirection:
                break;
            default:
                break;
        }
    }
}

View代码

<Window x:Class="Monitor.Views.Misc.MainViewChart"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Monitor.Views.Misc"
        xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
        xmlns:properties="clr-namespace:Monitor.Properties"
        xmlns:charting="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=DotNetProjects.DataVisualization.Toolkit"
        mc:Ignorable="d"
        Title="MainViewChart" Height="600" Width="1024"
        WindowStyle="None"
        WindowStartupLocation="CenterScreen"
        ResizeMode="NoResize"
        WindowState="Maximized">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="80"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <DockPanel Background="{StaticResource Blue4}" HorizontalAlignment="Stretch">
            <Label Content="" DockPanel.Dock="Left" Style="{StaticResource LabelScreenTitle}"/>
            <Button Focusable="False" Foreground="White" Background="Transparent" BorderBrush="{x:Null}" Width="80" HorizontalAlignment="Right" DockPanel.Dock="Right" Style="{StaticResource NoHover}" Click="Button_Click">
                <iconPacks:Material Kind="Close" Width="50" Height="50"/>
            </Button>
        </DockPanel>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="4*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <charting:Chart x:Name="MyChart" Background="#f8f8f8ff" BorderBrush="Transparent" Grid.Column="0">
                <charting:Chart.Series>
                    <charting:LineSeries Title="Your Series Title"
                            ItemsSource="{Binding CurrentDataSet}"
                            IndependentValueBinding="{Binding IndependentValuePath}"
                            DependentValueBinding="{Binding DependentValuePath}">
                        <charting:LineSeries.DataPointStyle>
                            <Style TargetType="charting:LineDataPoint">
                                <Setter Property="Background" Value="Blue"/>
                                <Setter Property="Width" Value="0"/>
                                <Setter Property="Height" Value="0"/>
                            </Style>
                        </charting:LineSeries.DataPointStyle>
                    </charting:LineSeries>
                </charting:Chart.Series>
                <charting:Chart.Axes>
                    <charting:LinearAxis Orientation="X" Title="{x:Static properties:Resources.Display_Time}"/>
                    <charting:LinearAxis Orientation="Y" Title="{Binding ChartUnits}"/>
                </charting:Chart.Axes>
                <charting:Chart.LegendStyle>
                    <Style TargetType="Control">
                        <Setter Property="Width" Value="0"/>
                        <Setter Property="Height" Value="0"/>
                    </Style>
                </charting:Chart.LegendStyle>
            </charting:Chart>
            <Grid Grid.Column="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="8*"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Button Grid.Row="0" Command="{Binding PreviousDataSetCommand}" Margin="1">
                    <iconPacks:Material Kind="ChevronUp" Width="25" Height="25"/>
                </Button>
                <UniformGrid Grid.Row="1" Rows="6" Margin="1">
                    <Button Content="test" Margin="1" Style="{StaticResource NormalButton}"/>
                    <Button Content="test" Margin="1" Style="{StaticResource NormalButton}"/>
                    <Button Content="test" Margin="1" Style="{StaticResource NormalButton}"/>
                    <Button Content="test" Margin="1" Style="{StaticResource NormalButton}"/>
                    <Button Content="test" Margin="1" Style="{StaticResource NormalButton}"/>
                    <Button Content="test" Margin="1" Style="{StaticResource NormalButton}"/>
                </UniformGrid>
                <Button Grid.Row="2" Command="{Binding PreviousDataSetCommand}" Margin="1">
                    <iconPacks:Material Kind="ChevronDown" Width="25" Height="25"/>
                </Button>
            </Grid>
        </Grid>
        
    </Grid>
</Window>

解决方案

1. 修正X轴类型为DateTimeAxis

X轴绑定的SampleTime是时间类型,当前使用的LinearAxis无法适配时间数据,需替换为DateTimeAxis:

<charting:Chart.Axes>
    <charting:DateTimeAxis Orientation="X" Title="{x:Static properties:Resources.Display_Time}"/>
    <charting:LinearAxis Orientation="Y" Title="{Binding ChartUnits}"/>
</charting:Chart.Axes>

2. 修正LineSeries的绑定属性

对于动态指定属性名称的场景,应使用IndependentValuePath和DependentValuePath而非Binding语法:

<charting:LineSeries Title="Your Series Title"
        ItemsSource="{Binding CurrentDataSet}"
        IndependentValuePath="{Binding IndependentValuePath}"
        DependentValuePath="{Binding DependentValuePath}">

3. 补全ViewModel的switch分支

当前仅实现了AmbientTemp分支,其他数据项未设置DependentValuePath会导致绑定为空引发错误,补全所有分支并设置对应单位:

switch (_currentChartItem)
{
    case DataProperty.AmbientTemp:
        ChartTitle = nameof(Sample_Data.AmbientTemp);
        DependentValuePath = nameof(Sample_Data.AmbientTemp);
        ChartUnits = "°C";
        break;
    case DataProperty.RelativeHumidity:
        ChartTitle = nameof(Sample_Data.RelativeHumidity);
        DependentValuePath = nameof(Sample_Data.RelativeHumidity);
        ChartUnits = "%";
        break;
    case DataProperty.BarometricPressure:
        ChartTitle = nameof(Sample_Data.BarometricPressure);
        DependentValuePath = nameof(Sample_Data.BarometricPressure);
        ChartUnits = "hPa";
        break;
    case DataProperty.WindSpeed:
        ChartTitle = nameof(Sample_Data.WindSpeed);
        DependentValuePath = nameof(Sample_Data.WindSpeed);
        ChartUnits = "m/s";
        break;
    case DataProperty.WindDirection:
        ChartTitle = nameof(Sample_Data.WindDirection);
        DependentValuePath = nameof(Sample_Data.WindDirection);
        ChartUnits = "°";
        break;
    default:
        break;
}

4. 验证数据有效性

确保DataLogger.Instance.ReadLastNSamples(N_RECORDS)返回的数据集非空,且每条数据的SampleTime和对应Y值均为有效类型(时间类型/数值类型),避免空值或类型不匹配导致轴无法识别。

内容的提问来源于stack exchange,提问作者Baddack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:20:53