【问题标题】:PieChart Does Not Show Up饼图不显示
【发布时间】:2016-05-11 18:22:30
【问题描述】:

我需要显示PieChart,我目前正在使用Modern UI (Metro) Charts。我确实复制了文档中的代码,问题是我总是在屏幕上有边框和标题,但没有图表。

XAML

<UserControl x:Class="Projet.Recources0.Statistique.Ad_Aj"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:mui="http://firstfloorsoftware.com/ModernUI"
         xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
         xmlns:chart="clr-namespace:De.TorstenMandelkow.MetroChart;assembly=De.TorstenMandelkow.MetroChart"
         mc:Ignorable="d" d:DesignWidth="1000" Height="670">

<UserControl.Resources>
    <Style x:Key="MinimalChartStyle" TargetType="{x:Type chart:ChartBase}">
        <Setter Property="Width" Value="500"/>
        <Setter Property="Height" Value="500"/>            
    </Style>
</UserControl.Resources>
<Grid >
    <chart:PieChart
    Style="{StaticResource MinimalChartStyle}"
    ChartTitle="Minimal Pie Chart"
    ChartSubTitle="Chart with fixed width and height"
    SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" >
        <chart:PieChart.Series>
            <chart:ChartSeries
            SeriesTitle="Errors"
            DisplayMember="Category"
            ValueMember="Number"
            ItemsSource="{Binding Path=Errors}" />
        </chart:PieChart.Series>
    </chart:PieChart>
</Grid>

CS

using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Projet.Recources0.Statistique
{
    /// <summary>
    /// Interaction logic for Ad_Aj.xaml
    /// </summary>

    public partial class Ad_Aj : UserControl
    {
        public ObservableCollection<TestClass> Errors { get; private set; }

        public Ad_Aj()
        {
            Errors = new ObservableCollection<TestClass>();
            Errors.Add(new TestClass() { Category = "Globalization", Number = 75 });
            Errors.Add(new TestClass() { Category = "Features", Number = 2 });
            Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 });
            Errors.Add(new TestClass() { Category = "Correctness", Number = 83});
            Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 });
        }

        private object selectedItem = null;
        public object SelectedItem
        {
            get
            {
                return selectedItem;
            }
            set
            {
                // selected item has changed
                selectedItem = value;                
            }
        }
    }

    // class which represent a data point in the chart
    public class TestClass
    {
        public string Category { get; set; }

        public int Number { get; set; }
    }
}

【问题讨论】:

    标签: c# wpf xaml charts


    【解决方案1】:

    创建一个ViewModel 来保存图表的数据并将其分配给您的DataContext,如下所示:

    XAML:

    <Window x:Class="WpfApplication222.Window2"
        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:chart="clr-namespace:De.TorstenMandelkow.MetroChart;assembly=De.TorstenMandelkow.MetroChart" 
        xmlns:local="clr-namespace:WpfApplication222"
        mc:Ignorable="d"
        Title="Window2" Height="350" Width="525">
    
    <Window.DataContext>
        <local:PieChartViewModel/>
    </Window.DataContext>
    
    <Grid>
        <chart:PieChart
            ChartTitle="Minimal Pie Chart"
            ChartSubTitle="Chart with fixed width and height"
            SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" >
            <chart:PieChart.Series>
                <chart:ChartSeries
                    SeriesTitle="Errors"
                    DisplayMember="Category"
                    ValueMember="Number"
                    ItemsSource="{Binding Path=Errors}" />
            </chart:PieChart.Series>
        </chart:PieChart>
    </Grid>
    

    视图模型:

    public class PieChartViewModel
    {
        public ObservableCollection<TestClass> Errors { get; private set; }
    
        public PieChartViewModel()
        {
            Errors = new ObservableCollection<TestClass>();
            Errors.Add(new TestClass() { Category = "Globalization", Number = 75 });
            Errors.Add(new TestClass() { Category = "Features", Number = 2 });
            Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 });
            Errors.Add(new TestClass() { Category = "Correctness", Number = 83 });
            Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 });
        }
    }
    

    编辑:除了像以前那样在 XAML 中创建 ViewModel 之外,您还可以按如下方式动态地进行操作:

    XAML:

    Window x:Class="WpfApplication222.Window2"
        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:chart="clr-namespace:De.TorstenMandelkow.MetroChart;assembly=De.TorstenMandelkow.MetroChart" 
        xmlns:local="clr-namespace:WpfApplication222"
        mc:Ignorable="d"
        Title="Window2" Height="350" Width="525" Loaded="Window_Loaded">
    
    <Grid>
        <chart:PieChart
            ChartTitle="Minimal Pie Chart"
            ChartSubTitle="Chart with fixed width and height"
            SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" >
            <chart:PieChart.Series>
                <chart:ChartSeries
                    SeriesTitle="Errors"
                    DisplayMember="Category"
                    ValueMember="Number"
                    ItemsSource="{Binding Path=Errors}" />
            </chart:PieChart.Series>
        </chart:PieChart>
    </Grid>
    

    CS:

    public partial class Window2 : Window
    {
        PieChartViewModel viewModel;
    
        public Window2()
        {
            InitializeComponent();
        }
    
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            viewModel = new PieChartViewModel();
    
            viewModel.Errors.Add(new TestClass() { Category = "Globalization", Number = 75 });
            viewModel.Errors.Add(new TestClass() { Category = "Features", Number = 2 });
            viewModel.Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 });
            viewModel.Errors.Add(new TestClass() { Category = "Correctness", Number = 83 });
            viewModel.Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 });
    
            DataContext = viewModel;
        }
    }
    

    视图模型:

    public class PieChartViewModel
    {
        public ObservableCollection<TestClass> Errors { get; private set; }
    
        public PieChartViewModel()
        {
            Errors = new ObservableCollection<TestClass>();
        }
    }
    

    【讨论】:

    • 之所以可行,是因为您设置了DataContextUserControl。这是原始海报代码中缺少的部分。
    • 这是标准的MVVM
    • 没错。但是您也可以将控件的 DataContext 绑定到自身,这是原始发布者试图做的。您提供了有效的代码,但没有明确说明原始海报问题的答案是什么。 :)
    • 如何创建视图模型
    • 请参阅我的帖子中的EDIT,了解动态创建和填充ViewModel
    【解决方案2】:

    所以你走上正轨了!你只是少了一行代码!

    public partial class Ad_Aj : UserControl
    {
        public ObservableCollection<TestClass> Errors { get; private set; }
    
        public Ad_Aj()
        {
            /*
             * ----------------------------
             * This is line you're missing.
             * ----------------------------
             */
            DataContext = this;
            /*
             * ----------------------------
             */
            Errors = new ObservableCollection<TestClass>();
            Errors.Add(new TestClass() { Category = "Globalization", Number = 75 });
            Errors.Add(new TestClass() { Category = "Features", Number = 2 });
            Errors.Add(new TestClass() { Category = "ContentTypes", Number = 12 });
            Errors.Add(new TestClass() { Category = "Correctness", Number = 83});
            Errors.Add(new TestClass() { Category = "Best Practices", Number = 29 });
        }
    }
    

    这是 MVVM,但它不是真正的 MVVM。真正的 MVVM 有一个单独的 ViewModel 类。您在这里所做的是使用 View 的 Code-Behind 作为您的 ViewModel。它有效,没有人会在这方面与你抗衡。但是,如果您尝试做真正的 MVVM,那么您需要分离出您的类。

    jstreet has a great answer/example 了解如何在 XAML 中将 DataContext(也称为“绑定”)设置为 ViewModel。

    <Window.DataContext>
        <local:PieChartViewModel />
    </Window.DataContext>
    

    但是,请注意他正在使用单独的 ViewModel 类。您在问题中提供的代码确实 not 这样做,所以我不确定如何以同样的方式做到这一点。此外,值得一提的是,如果您的 ViewModel 类使用构造函数依赖注入或具有参数,那么您将不得不使用一些魔法来使其工作。如果是这样的话,在构造函数中设置它会更容易。

    【讨论】:

      【解决方案3】:

      我不是控件方面的专家,但我猜您的ItemsSource 绑定失败了。 Errors 集合作为属性在用户控件上,默认情况下,您对 ItemsSource 的绑定将脱离 DataContext,我认为在您的情况下为 null。要直接通过绑定获取控件,您可能会通过执行以下操作使其与 RelativeSource 标记扩展一起使用(假设您将“本地”映射到 Ad_Aj 所在的命名空间):

      ItemsSource = "{Binding RelativeSource={RelativeSource AncestorType=local:Ad_Aj, Mode=FindAncestor}, Path=Errors}"
      

      我认为尽管您希望将您的 Errors 信息放在视图模型中,然后将其设置为数据上下文并使用绑定,因为 Errors 信息实际上是数据并且与用户界面。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多