2

我正在创建 DataVisualization.Chart 类型的 UserControl 组件。我正在构建基于 url 示例的组件:http://www.dotnetcurry.com/ShowArticle.aspx?ID=553。此图表将生成选择为柱、条、线、饼图类型的图表...在组件的构造中,我插入的数据源比通过另一个视图传递的数据源。到现在为止还挺好。正常生成所有类型的图表。我现在需要做的是对组件进行 3 次修改。但我找不到解决这些修改的方法:

  • 当用户将鼠标放在图形生成的值上时,工具提示出现对象的值。我需要的是工具提示文本显示为 IndependentValuePath,这将是名称 + 值,格式如下:“名称(价值)”;
  • 生成图表时,它会根据图表的 x 轴或 y 轴(如图所示)作为一种标签插入。我需要删除它(图片中的示例);
  • 对于 Column 类型的图形(可能还有其他尚未确认的图形),矩形的轮廓必须与内部颜色相同。除了颜色相同之外,每个矩形都会根据预定义的范围改变颜色,这将作为上一个 View 的 DataSource 传递。这是什么:如果值低于 200,则颜色为红色,如果在 200 到 350 之间,则为黄色……以此类推。我将有大约 5 个限制;

示例修改

PS:最后THIStooltip

有谁知道我如何对这些图表和工具提示进行样式化?

最好的问候,古斯塔沃

编辑:这是我的用户控制图:

<UserControl x:Class="Library.Core.GUI.WPF.Controls.ChartUCControl"
         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:ct="clr-namespace:Library.Core.GUI.WPF.Controls"
         xmlns:chart="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
         mc:Ignorable="d" 
         x:Name="ChartUCControl1">
<UserControl.Resources>

    <Style TargetType="chart:ColumnDataPoint">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type chart:ColumnDataPoint}">

                        <!--<Border BorderThickness="0" Background="Red" ToolTip="asdfasdf"/>-->
                        <Rectangle>
                            <Rectangle.Fill>
                                <LinearGradientBrush>
                                    <GradientStop Color="Black" Offset="0"/>
                                    <GradientStop Color="White" Offset="1"/>
                                </LinearGradientBrush>
                            </Rectangle.Fill>
                        </Rectangle>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</UserControl.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="auto"/>
    </Grid.RowDefinitions>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <ScrollViewer VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Width="auto"
                      HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
            <chart:Chart Name="chartView" Grid.Row="0" Title="{Binding TitleGraphic, Mode=TwoWay, ElementName=ChartUCControl1, UpdateSourceTrigger=PropertyChanged}" 
                       ScrollViewer.HorizontalScrollBarVisibility="Auto"
                       ScrollViewer.VerticalScrollBarVisibility="Auto"
                       ScrollViewer.IsDeferredScrollingEnabled="True"
                       Width="{Binding WidthScrollViewer, Mode=TwoWay, ElementName=ChartUCControl1, UpdateSourceTrigger=PropertyChanged}"
                       MinWidth="{Binding MinWidthScrollViewer, Mode=TwoWay, ElementName=ChartUCControl1, UpdateSourceTrigger=PropertyChanged}"
                       HorizontalAlignment="{Binding HorizontalAlignmentGraphic, Mode=TwoWay, ElementName=ChartUCControl1, UpdateSourceTrigger=PropertyChanged}"  >

                <chart:Chart.Series>
                    <chart:ColumnSeries >
                        <ToolTipService.ToolTip>
                            <ContentControl Content="asdçlfkj"/>
                        </ToolTipService.ToolTip>
                        <chart:ColumnSeries.IndependentAxis>
                            <chart:CategoryAxis Orientation="X" Visibility="Visible" Height="0"/>
                        </chart:ColumnSeries.IndependentAxis>
                    </chart:ColumnSeries>
                </chart:Chart.Series>
                <!--<ToolTipService.ToolTip>
                    <ContentControl Content="{TemplateBinding IndependentValue}" />
                </ToolTipService.ToolTip>-->
                <!--PreviewMouseMove="chartView_PreviewMouseMove"-->

                <!--<chart:Chart.Series>
                    <chart:ColumnSeries>
                        <chart:DataPointSeries.DataPointStyle>
                            <Style TargetType="chart:ColumnDataPoint">
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type chart:ColumnDataPoint}">
                                            <Border BorderBrush="Black" >
                                                <ToolTipService.ToolTip>
                                                <ContentControl Content="{Binding ToolTip}"/>
                                            </ToolTipService.ToolTip>
                                                <Border BorderBrush="Black" BorderThickness="1"/>
                                                <ToolTipService.ToolTip>
                                                    <ContentControl Content="asçldfkj"/>
                                                </ToolTipService.ToolTip>
                                            </Border>
                                            <ToolTip Content="çlkjasf"/>

                                            <Rectangle>
                                                <Rectangle.Fill>
                                                    <SolidColorBrush Color="Blue"/>
                                                </Rectangle.Fill>
                                            </Rectangle>

                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </chart:DataPointSeries.DataPointStyle>
                    </chart:ColumnSeries>
                </chart:Chart.Series>-->

                <!--<Style TargetType="{x:Type chart:ColumnDataPoint}">
                            <Setter Property="Background" Value="Orange" />
                            <Setter Property="BorderBrush" Value="Black" />
                            <Setter Property="BorderThickness" Value="1" />
                            <Setter Property="IsTabStop" Value="False" />
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type chart:ColumnSeries}">
                                        <Border BorderBrush="Azure" BorderThickness="10" Opacity="10" x:Name="Root">
                                            <Grid Background="Black">
                                                <Rectangle>
                                                    <Rectangle.Fill>
                                                        <LinearGradientBrush>
                                                            <GradientStop Color="Black" Offset="0" />
                                                            <GradientStop Color="Black" Offset="1" />
                                                        </LinearGradientBrush>
                                                    </Rectangle.Fill>
                                                </Rectangle>
                                                <Border BorderBrush="#ccffffff" BorderThickness="1">
                                                    <Border BorderBrush="#77ffffff" BorderThickness="1" />
                                                </Border>
                                                <Rectangle x:Name="SelectionHighlight" Fill="Red" Opacity="0" />
                                                <Rectangle x:Name="MouseOverHighlight" Fill="White" Opacity="0" />
                                            </Grid>
                                            <ToolTipService.ToolTip>
                                                <ContentControl Content="as" />
                                            </ToolTipService.ToolTip>
                                        </Border>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>-->

                <!--<ToolTipService.ToolTip>
                                                    <ContentControl Content="{Binding Identificacao}"/>
                                                </ToolTipService.ToolTip>-->
                <!--<Grid>
                                                <Rectangle>
                                                    <Rectangle.Fill>
                                                        <LinearGradientBrush>
                                                            <GradientStop Color="Blue" Offset="0"/>
                                                            <GradientStop Color="Black" Offset="1"/>
                                                        </LinearGradientBrush>
                                                    </Rectangle.Fill>
                                                </Rectangle>
                                            </Grid>-->

                <chart:Chart.Axes>
                    <chart:LinearAxis Orientation="X" Interval="{Binding IntervalAxis, ElementName=ChartUCControl1, Mode=TwoWay}" 
                                    MouseEnter="chartView_PreviewMouseMove"
                                    Maximum="{Binding MaximumAxis, ElementName=ChartUCControl1, Mode=TwoWay}"/>
                    <!-- This section configures labels of X Orientation -->
                    <chart:CategoryAxis Orientation="X" Visibility="Hidden"/>
                </chart:Chart.Axes>

                <chart:Chart.LegendStyle>
                    <Style TargetType="Control">
                        <Setter Property="Width" Value="0"/>
                        <Setter Property="Height" Value="0"/>
                    </Style>
                </chart:Chart.LegendStyle>

                <chart:Chart.PlotAreaStyle>
                    <Style TargetType="Grid">
                        <Setter Property="Background" Value="Transparent"/>
                        <!--<Setter Property="ToolTip" Value="{x:Null}"/>-->
                    </Style>
                </chart:Chart.PlotAreaStyle>
            </chart:Chart>
        </ScrollViewer>
    </Grid>
</Grid>
</UserControl>

如果需要查看我的代码隐藏:

namespace Library.Core.GUI.WPF.Controls
{
    public partial class ChartUCControl : UserControl, INotifyPropertyChanged
    {
        #region Constructors

        public ChartUCControl()
        {
            InitializeComponent();
        }

        #endregion

        #region ChartType Property

        public static ChartTypes GetChartType(DependencyObject d)
        {
            return (ChartTypes)d.GetValue(ChartTypeProperty);
        }

        public static void SetChartType(DependencyObject d, ChartTypes value)
        {
            d.SetValue(ChartTypeProperty, value);
        }

        public static readonly DependencyProperty ChartTypeProperty =
            DependencyProperty.RegisterAttached(
                "ChartType",
                typeof(ChartTypes),
                typeof(ChartUCControl),
                new FrameworkPropertyMetadata(ChartTypeChangedCallback)
                );

        private static void ChartTypeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Chart instance = (d as Chart);
            if (instance.IsNull())
                return;

            SetChartType(d, (ChartTypes)e.NewValue);

            ChartUCControl instance2 = (d as ChartUCControl);
        }

        private ChartTypes chartType;
        public ChartTypes ChartType
        {
            get { return chartType; }
            set { chartType = value; }
        }

        #endregion

        #region ChartAreaSelected Property

        public static readonly DependencyProperty ChartAreaProperty =
            DependencyProperty.RegisterAttached(
                "ChartArea",
                typeof(Boolean),
                typeof(ChartUCControl),
                        new FrameworkPropertyMetadata(ChartAreaChangedCallback));

        private static void ChartAreaChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ChartUCControl instance = (d as ChartUCControl);

            if (instance.IsNull())
                return;

            instance.ChartArea = (Boolean)e.NewValue;
        }

        private Boolean chartArea;
        public Boolean ChartArea
        {
            get { return chartArea; }
            set
            {
                chartArea = value;
                if (value)
                {
                    cmbChart.SelectedItem = ChartTypes.Area;
                    DoRenderizeGraphic();
                }
            }
        }

        #endregion

        #region ChartBarSelected Property

        public static readonly DependencyProperty ChartBarProperty =
            DependencyProperty.RegisterAttached(
                "ChartBar",
                typeof(Boolean),
                typeof(ChartUCControl),
                new FrameworkPropertyMetadata(ChartBarChangedCallback));

        private static void ChartBarChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ChartUCControl instance = (d as ChartUCControl);

            if (instance.IsNull())
                return;

            instance.ChartBar = (Boolean)e.NewValue;
        }

        private Boolean chartBar;
        public Boolean ChartBar
        {
            get { return chartBar; }
            set
            {
                chartBar = value;
                if (value)
                {
                    cmbChart.SelectedItem = ChartTypes.Bar;
                    DoRenderizeGraphic();
                }
            }
        }

        #endregion

        #region ChartColumnSelected Property

        public static readonly DependencyProperty ChartColumnProperty =
            DependencyProperty.RegisterAttached(
                "ChartColumn",
                typeof(Boolean),
                typeof(ChartUCControl),
                new FrameworkPropertyMetadata(ChartColumnChangedCallback)
                );

        private static void ChartColumnChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ChartUCControl instance = (d as ChartUCControl);
            if (instance.IsNull())
                return;

            instance.ChartColumn = (Boolean)e.NewValue;
        }

        private Boolean chartColumn;
        public Boolean ChartColumn
        {
            get { return chartColumn; }
            set
            {
                chartColumn = value;

                if (value)
                {
                    cmbChart.SelectedItem = ChartTypes.Columns;
                    DoRenderizeGraphic();
                }
            }
        }

        #endregion
        #region ChartLinesSelected Property

        public static readonly DependencyProperty ChartLinesProperty =
            DependencyProperty.RegisterAttached(
                "ChartLines",
                typeof(Boolean),
                typeof(ChartUCControl),
                new FrameworkPropertyMetadata(ChartLinesChangedCallback));

        private static void ChartLinesChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ChartUCControl instance = (d as ChartUCControl);
            if (instance.IsNull())
                return;

            instance.ChartLines = (Boolean)e.NewValue;
        }

        private Boolean chartLines;
        public Boolean ChartLines
        {
            get { return chartLines; }
            set
            {
                chartLines = value;
                if (value)
                {
                    cmbChart.SelectedItem = ChartTypes.Lines;
                    DoRenderizeGraphic();
                }
            }
        }

        #endregion

        #region FieldForIndependentValue Property

        /// <summary>
        /// String containing list of the only characters allowed, others will be filtered
        /// </summary>
        public String FieldForIndependentValue
        {
            get { return (String)GetValue(FieldForIndependentValueProperty); }
            set { SetValue(FieldForIndependentValueProperty, value); }
        }

        public static readonly DependencyProperty FieldForIndependentValueProperty =
            DependencyProperty.Register("FieldForIndependentValue", typeof(String), typeof(ChartUCControl));

        #endregion

        #region FieldForDependentValue Property

        /// <summary>
        /// String containing list of the only characters allowed, others will be filtered
        /// </summary>
        public String FieldForDependentValue
        {
            get { return (String)GetValue(FieldForDependentValueProperty); }
            set { SetValue(FieldForDependentValueProperty, value); }
        }

        public static readonly DependencyProperty FieldForDependentValueProperty =
            DependencyProperty.Register("FieldForDependentValue", typeof(String), typeof(ChartUCControl));

        #endregion

        #region TitleGraphic Property

        public String TitleGraphic
        {
            get { return (String)base.GetValue(TitleGraphicProperty); }
            set { base.SetValue(TitleGraphicProperty, value); }
        }

        public static readonly DependencyProperty TitleGraphicProperty =
            DependencyProperty.RegisterAttached(
                "TitleGraphic",
                typeof(String),
                typeof(ChartUCControl),
                new FrameworkPropertyMetadata(null)
                );

        #endregion

        #region MinWidthScrollViewer Property

        public String MinWidthScrollViewer
        {
            get { return (String)base.GetValue(MinWidthScrollViewerProperty); }
            set { base.SetValue(MinWidthScrollViewerProperty, value); }
        }

        public static readonly DependencyProperty MinWidthScrollViewerProperty =
            DependencyProperty.RegisterAttached(
            "MinWidthScrollViewer",
            typeof(String),
            typeof(ChartUCControl),
            new FrameworkPropertyMetadata(null));

        #endregion

        #region Width ScrollViewer Property

        public String WidthScrollViewer
        {
            get { return (String)base.GetValue(WidthScrollViewerProperty); }
            set { base.SetValue(WidthScrollViewerProperty, value); }
        }

        public static readonly DependencyProperty WidthScrollViewerProperty =
            DependencyProperty.RegisterAttached(
                "WidthScrollViewer",
                typeof(String),
                typeof(ChartUCControl),
                new FrameworkPropertyMetadata(null)
                );

        #endregion

        #region ItemsSource Property

        public IEnumerable ItemsSource
        {
            get { return (IEnumerable)base.GetValue(ItemsSourceProperty); }
            set { base.SetValue(ItemsSourceProperty, value); }
        }

        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.RegisterAttached(
            "ItemsSource",
            typeof(IEnumerable),
            typeof(ChartUCControl),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));

        #endregion

        #region Methods

        private void ImageButton_Click_1(object sender, RoutedEventArgs e)
        {
            DoRenderizeGraphic();
        }

        public void DoRenderizeGraphic()
        {
            while (this.chartView.Series.Count() - 1 >= 0)
                this.chartView.Series.Remove(this.chartView.Series[0]);

            DataPointSeries objChar = null;

            if (!cmbChart.SelectedItem.IsNull())
                switch ((ChartTypes)cmbChart.SelectedValue)
                {
                    case ChartTypes.Bar:
                        this.chartView.Series.Add(new BarSeries());
                        objChar = this.chartView.Series[0] as BarSeries;
                        break;

                    case ChartTypes.Columns:
                        this.chartView.Series.Add(new ColumnSeries());
                        objChar = this.chartView.Series[0] as ColumnSeries;

                        break;

                    case ChartTypes.Pie:
                        this.chartView.Series.Add(new PieSeries());
                        objChar = this.chartView.Series[0] as PieSeries;
                        break;

                    case ChartTypes.Lines:
                        this.chartView.Series.Add(new LineSeries());
                        objChar = this.chartView.Series[0] as LineSeries;
                        break;

                    case ChartTypes.Area:
                        this.chartView.Series.Add(new AreaSeries());
                        objChar = this.chartView.Series[0] as AreaSeries;
                        break;

                    default:
                        break;
                }

            if (!objChar.IsNull())
            {
                objChar.IsSelectionEnabled = true;

                objChar.DependentValuePath = FieldForDependentValue;
                objChar.IndependentValuePath = FieldForIndependentValue;
                objChar.ItemsSource = ItemsSource;


                if (this.chartView.Axes.Count > 0
                   && (!this.chartView.ActualAxes[0].IsNull() || !this.chartView.ActualAxes[0].DependentAxes.IsNull()))
                    foreach (var item in this.chartView.ActualAxes[0].DependentAxes)
                    {
                        this.chartView.ActualAxes[0].DependentAxes.Remove(item);
                    }

            }
        }

        #endregion

        #region Properties

        private String[] chartTypesList;
        public String[] ChartTypesList
        {
            get { return chartTypesList; }
            set
            {
                chartTypesList = value;
                OnPropertyChanged("ChartTypesList");
            }
        }

        private String chartTypeSelectedValue;
        public String ChartTypeSelectedValue
        {
            get { return chartTypeSelectedValue; }
            set
            {
                chartTypeSelectedValue = value;
                OnPropertyChanged("ChartTypeSelectedValue");
            }
        }

        #endregion

        #region INotifyPropertyChanged event and method

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(String info)
        {
            if (!PropertyChanged.IsNull())
                PropertyChanged(this, new PropertyChangedEventArgs(info));
        }

        #endregion

        #region Preview Mouse events

        private void chartView_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            var t = ((e.OriginalSource) as FrameworkElement).DataContext;

            if (!t.IsNull() && e.OriginalSource.GetType().Equals(typeof(System.Windows.Shapes.Rectangle)))
            {
                Object a = null;

                foreach (PropertyInfo item in ((e.OriginalSource) as FrameworkElement).DataContext.GetType().GetProperties())
                {
                    a = item.GetValue(((e.OriginalSource) as FrameworkElement).DataContext, null);
                    break;
                }

                if (a == null)
                    a = "";
                ((FrameworkElement)(e.OriginalSource)).ToolTip = a;
            }
        }

        #endregion

        #region ReflectionReturn Seekers

        public List<Control> FindAllControls(DependencyObject parent)
        {
            var list = new List<Control>() { };

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                if (child is Control)
                {
                    list.Add(child as Control);

                }
                list.AddRange(FindAllControls(child));
            }
            return list;
        }

        public IEnumerable<FieldInfo> GetAllFields(Type t)
        {
            if (t.IsNull())
                return Enumerable.Empty<FieldInfo>();

            BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;

            return t.GetFields(flags).Union(GetAllFields(t.BaseType));
        }

        #endregion

    }
    #region Enum

    public enum ChartTypes
    {
        Bar,
        Columns,
        Pie,
        Lines,
        Area
    }

    #endregion
}
4

1 回答 1

2

答案 1

您可以在ColumnDataPoint样式中声明工具提示。最简单的方法是向模型添加一个新属性并绑定到它。

例如,如果图表项类有 2 个属性,则为工具提示添加第 3 个属性:

public class ChartItem
{
    public string Title { get; set; } // coil456

    public double Value { get; set; } // 334

    public string TooltipLabel 
    { 
        get { return string.Format("{0}({1})", this.Title, this.Value); } // coil456(334)
    }
}

然后为数据点样式添加绑定:

<Style x:Key="ColumnDataPointStyle" TargetType="chart:ColumnDataPoint">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type chart:ColumnDataPoint}">
                <Rectangle ToolTipService.ToolTip="{Binding TooltipLabel}">
                    <Rectangle.Fill>
                        <LinearGradientBrush>
                            <GradientStop Color="Black" Offset="0"/>
                            <GradientStop Color="White" Offset="1"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

更改后的行:ToolTipService.ToolTip="{Binding TooltipLabel}". 我使用了一个简单的绑定,因为我绑定到 DataContext,而不是模板。

然后更改您的代码隐藏,以便列系列使用以下样式:

case ChartTypes.Columns:
    objChar = new ColumnSeries();
    objChar.DataPointStyle = (Style)this.Resources["ColumnDataPointStyle"];
    this.chartView.Series.Add(objChar);

    break;

同样,您可以使用AxisLabelStyle属性和样式为轴添加工具提示NumericAxisLabel

答案 3 一切都以同样的方式:向模型添加一个属性并绑定到它。

C# 模型

public class ChartItem
{
    public string Title { get; set; }

    public double Value { get; set; }

    public string TooltipLabel 
    { 
        get { return string.Format("{0}({1})", this.Title, this.Value); } 
    }

    public SolidColorBrush ColumnBrush
    {
        get 
        { 
            if (this.Value < 200)
            {
                return Brushes.Red;
            }
            else if (this.Value < 350)
            {
                return Brushes.Yellow;
            }
            else
            {
                return Brushes.Green;
            }
        } 
    }
}

模板

<Style x:Key="ColumnDataPointStyle" TargetType="chart:ColumnDataPoint">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type chart:ColumnDataPoint}">
                <Rectangle ToolTipService.ToolTip="{Binding TooltipLabel}" Fill="{Binding ColumnBrush}">
                </Rectangle>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
于 2013-03-19T08:26:33.910 回答