【问题标题】:How can I bind an axis of a chart to a specific index of a List()?如何将图表的轴绑定到 List() 的特定索引?
【发布时间】:2013-08-01 13:03:03
【问题描述】:

我正在尝试使用 WPF 工具包创建图表,其中 Y 轴由 List() 中的值更新。我正在尝试通过特定索引访问该值。目前,绑定到List() 而不是int 的索引会创建“没有合适的轴可用于绘制相关值”。例外。

这是我目前所拥有的,请注意我尝试让 DependentValuePath 访问索引:

<Charting:LineSeries VerticalAlignment="Stretch" 
                     HorizontalAlignment="Stretch" 
                     ItemsSource="{Binding Path=MemoryStats}" 
                     IndependentValuePath="Timestamp" 
                     DependentValuePath="ByteCount[0]"
                     Title="Data Points">

这是 MemoryStats 值在后面的代码中包含的内容:

public List<int> ByteCount { get; set; }
public DateTime Timestamp { get; set; }

当 XAML 中的 LineSeries 具有属性 DependentValuePath="ByteCount" 并且代码隐藏使用简单的 int 时,图表可以正常工作:

public int ByteCount { get; set; }
public DateTime Timestamp { get; set; }

如何让它绑定到 List() 而不是 int 的索引?

编辑

我已经能够通过命名它的索引从后面的代码中获取列表中的具体值,但是在创建图表时会动态生成多个LineSeries。我想将每一个绑定到List&lt;int&gt;() 的索引,我每隔一秒左右重新创建一次。

这是MemoryStats 用来更新用户界面的完整方法。它通过将所有 LineSeries Y 值更新为单个 ByteCount int 来工作,因此目前所有行看起来都一样。

    public class MemorySample
    {
        public static MemorySample Generate(List<int> dataPoints)
        {

            return new MemorySample
            {
                ByteCount = dataPoints[0],
                Timestamp = DateTime.Now
            };
        }

        public int ByteCount { get; set; }
        public DateTime Timestamp { get; set; }
    }

当然,我希望所有LineSeries 都不同。我想让图表的每个LineSeries 的 X 轴为TimeStamp(所以它们都有相同的时间戳),并且各种LineSeries 的 Y 轴值由整数的List() 更新,每个都使用List()的单独索引

我将尝试实现一个类型转换器,但我不完全确定何时/何地这样做。

编辑 2

我让它按照我想要的方式工作!找到了很多帮助from this S.O. question regarding using multiple series in a line chart.

看起来好像类型转换器也可以工作,所以 Shimrod 已经回答了这个问题。然而,我最终做的是将 LineSeries 的ItemSource 绑定到一个索引,然后检索该索引内容的数据。

所以,LineSeries 是这样的:

        <Charting:LineSeries VerticalAlignment="Stretch" 
                            HorizontalAlignment="Stretch" 
                            ItemsSource="{Binding [0]}" 
                            IndependentValuePath="X" 
                            DependentValuePath="Y"
                            Title="Data Points">
        </Charting:LineSeries>

注意ItemSource 绑定中的索引。在后面的代码中,我将控件的DataContext 设置为ObservableCollection,它包含一个从“IList”继承的对象(您可以使用任何这样做的对象),并且该对象包含包含属性 XY 属性。

   public ObservableCollection<InheritsFromIList<ObjectWithXandYProperties>> VariableDataContextIsSetTo { get; set; }

访问ObservableCollection 的特定索引将返回列表。然后,该列表中的项目将显示在图表上。

【问题讨论】:

    标签: c# .net wpf xaml wpftoolkit


    【解决方案1】:

    我认为最简单的方法是在您的类中添加一个属性,该属性将是Listint 值。

    例如

    int val { get { return ByteCount[0]; } }
    

    或者您也可以创建一个转换器,它将列表作为绑定和索引作为参数,并返回所需的值。

    例如(这个我没试过)

    public class ElementOfListConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is IList && parameter is int)
            {
                var lst = value as IList;
                int pos = (int)parameter;
    
                if (lst.Count >= pos)
                {
                    return lst[pos];
                }
            }
    
            return null;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    编辑

    这些是使用转换器的步骤:

    1. 创建类(ElementOfListConverter),如前所示。
    2. 添加一个指向转换器位置的新 xml 命名空间。例如。 xmlns:local="clr-namespace:WpfApplication2"
    3. 在 Window(或 UserControl)的资源中,添加对转换器的引用,如下所示:

      <Window.Resources>
          <local:ElementOfListConverter x:Key="ElemOfList" />
      </Window.Resources>
      
    4. 在您的绑定中,指定要使用的转换器(使用其密钥{Binding YourElement, Converter={StaticResource ElemOfList}, ConverterParameter=0}

    这种方法的优点是可以直接在xaml中指定元素的索引。您还可以使用MultiBindingMultiValueConverter 将此值绑定到其他值。 (如果您需要更多信息,请参阅this question on S.O.

    【讨论】:

    • 我不太熟悉在哪里实现类型转换器,但我会试一试。如果有帮助,我会更详细地更新我的问题。我还没有正确实施解决方案,但现在我将其归结为我自己的经验不足并接受答案。
    • 我添加了一个示例代码,如果您需要更多信息,请随时告诉我!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多