如何在WPF图表中触发PropertyChanged事件

时间:2017-02-07 00:39:14

标签: c# wpf

WPF图表控件在切换复选框时成功添加和清除数据并刷新图表,因为它包含' UpdateSourceTrigger = PropertyChanged'但是,我不知道如何在后面的代码中触发相同的事件来自OnDataAnalyzed(字符串数据,int channelNumber)方法。

public partial class MainWindowChart : Window
{
    public MainWindowChart()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void Notify(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public void OnDataAnalyzed(string data, int channelNumber)
    {
        //Code needed to trigger PropertyChanged event that updates BarChart1.
    }
}

MainWindowChart.xaml

<Window x:Class="WPFControlTester.MainWindowChart"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="589" Width="1008"
        xmlns:controls="clr-namespace:KeyhanControls.Chart;assembly=KeyhanControls"
        xmlns:my="clr-namespace:WPFControlTester">
    <Window.Resources>
        <my:Bool2Visibility x:Key="B2V"/>
    </Window.Resources>
    <Grid> 

        //Code removed for simplicity...

        <controls:BarChart x:Name="BarChart1" LegendPropertyName="WorkType" VerticalPropertyName="Value" HorizontalPropertyName="Year" FontFamily="Tahoma"
                        ItemsSource="{Binding Path=Data, RelativeSource={RelativeSource AncestorType=Window}}">

        //Code removed for simplicity...

        </controls:BarChart>
        <Border Grid.Column="1" BorderBrush="DarkGray" BorderThickness="1" Margin="10">
            <StackPanel Margin="5">
                <CheckBox Content="Can change bars visibility" IsChecked="{Binding Path=CanChangeLegendVisibility, ElementName=BarChart1, UpdateSourceTrigger=PropertyChanged}" />        
            </StackPanel>
        </Border>
    </Grid>
</Window>

命名空间KeyhanControls.Chart

[System.ComponentModel.DefaultProperty("Legends")]
public partial class BarChart : UserControl
{
    public BarChart()
    {
        InitializeComponent();
        this.DataContext = this;
    }

   //Code removed for simplicity...

    public static readonly DependencyProperty CanChangeLegendVisibilityProperty = DependencyProperty.Register("CanChangeLegendVisibility", typeof(bool), typeof(BarChart),
        new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (s, e) => { (s as BarChart).CanChangeLegendVisibility = (bool)e.NewValue; }));
    public bool CanChangeLegendVisibility
    {
        get
        {
            return (bool)GetValue(CanChangeLegendVisibilityProperty);
        }
        set
        {
            SetValue(CanChangeLegendVisibilityProperty, value);
            Notify("CanChangeLegendVisibility");
            Draw();
        }
    }

   //Code removed for simplicity...

    public event PropertyChangedEventHandler PropertyChanged;

    private void Notify(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

   //Code removed for simplicity...

}

[System.ComponentModel.DefaultEvent("IsVisibleChanged")]
[System.ComponentModel.DefaultProperty("LegendType")]
public class Legend : DependencyObject, INotifyPropertyChanged
{

    //Code removed for simplicity...

    private bool _isVisible = true;
    public bool IsVisible
    {
        get { return _isVisible; }
        set
        {
            if (_isVisible != value)
            {
                _isVisible = value;
                Notify("IsVisible");
                if (IsVisibleChanged != null)
                    IsVisibleChanged(this, new RoutedEventArgs());
            }
        }
    }

    public event RoutedEventHandler IsVisibleChanged;

    public event PropertyChangedEventHandler PropertyChanged;
    private void Notify(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}

//下面的代码更接近data和channelNumber参数源

clsAnalysis.cs

 public delegate void dlgAnalysis_Analyzed(string data, int channelNumber);
 public event dlgAnalysis_Analyzed analysis_Analyzed;

clsCommand.cs

 private void Analysis_DataAnalyzed(string data, int channelNumber)//Fired from the analysis module.
{
    transmitData(channelNumber, data);
}

public void newClientSelected(clsLVI_Generic_Item item)
{
    analysisModule = new clsAnalysis(SENSOR_DELIMITER, wMain.cSettings.SensitiveAnalysisMode)
    hookAnalysisEvents();
}

private void hookAnalysisEvents()
{
    analysisModule.analysis_Analyzed += wChart.OnDataAnalyzed;
}

2 个答案:

答案 0 :(得分:0)

我不确定我的以下解决方案是否理想。也许有人可以评论它和/或替代解决方案。感谢

    public void OnDataAnalyzed(string data, int channelNumber)
    {
       // MessageBox.Show("Analyzed");
        Data.Clear();
        Data.Add(new MyData() { Year = 1, Value = Convert.ToInt32(data.Substring(7, 2)), WorkType = WorkTypes.Violet });

        Application.Current.Dispatcher.BeginInvoke(
                DispatcherPriority.Normal,
                new Action(() => BarChart1.CanChangeLegendVisibility = true));
    }

答案 1 :(得分:0)

有两种方法可以解决这个问题,一种方法是更改​​事件处理程序并将其添加到事件中,如下所示:

public void OnDataAnalyzed(object sender, PropertyChangedArgs args)
{
    // whatever you do
}

PropertyChanged += OnDataAnalyzed;

这里的问题是你错过了当前为你的方法指定的参数可能不在PropertyChangedArgs中(我在你的代码中找不到它的结构)。我不确定那些参数适合哪里,因为两个例子中的代码都很多 - 如果你可以将它缩短到最相关的东西,我可以给你更多反馈吗?