单击按钮刷新实时图表事件



我有一个实时图表,我正在尝试对Button_Click事件执行值的刷新,但图表没有刷新。

我有两个TextBoxes,用户可以在其中选择他们想要查看的开始和结束日期,并使用butn_ExecuteQuery_Click来显示数据。

public HBDBreakdown()
{
InitializeComponent();
ChartValues();
}
private void ChartValues()
{
try
{
// Defines the variable for differnt lines.
List<double> SmallCommercialIndustValues = new List<double>();
List<double> ResidentialValues = new List<double>();
List<string> AnalystName = new List<string>();
SqlConnection connection = new SqlConnection("Data Source=WINDOWS-B1AT5HC\MSSQLSERVER2;Initial Catalog=CustomerRelations;user id=sa; password=Westside2$; Integrated Security=False;");
string selectQuery = ("SELECT Users.TX_EMPLOYEE, SUM(CASE WHEN d .REV_CLS <> 2 THEN 1 ELSE 0 END) AS Residential, SUM(CASE WHEN d .REV_CLS = 2 THEN 1 ELSE 0 END) AS SmallCommercialIndust FROM hb_Disputes AS d INNER JOIN Users ON d.ASSGNTO = Users.KY_USER_ID WHERE(d.OPENED >=@OPENED) AND(d.OPENED < @CLOSED) GROUP BY Users.TX_EMPLOYEE; ");
connection.Open();
SqlCommand command = new SqlCommand(selectQuery, connection);
command.Parameters.Add("@OPENED", SqlDbType.DateTime).Value = dtepicker_Open.Text;
command.Parameters.Add("@CLOSED", SqlDbType.DateTime).Value = dtepicker_DateResolved.Text;
SqlDataReader sqlReader = command.ExecuteReader();
while (sqlReader.Read())
{
// Check for DBNull and then assign the variable
if (sqlReader["SmallCommercialIndust"] != DBNull.Value)
SmallCommercialIndustValues.Add(Convert.ToInt32(sqlReader["SmallCommercialIndust"]));
// Check for DBNull and then assign the variable
if (sqlReader["Residential"] != DBNull.Value)
ResidentialValues.Add(Convert.ToInt32(sqlReader["Residential"]));
// Check for DBNull and then assign the variable
AnalystName.Add(Convert.ToString(sqlReader["TX_EMPLOYEE"]));
}

SeriesCollection = new SeriesCollection
{
new StackedColumnSeries
{
Title = "Residential",
Values = new ChartValues<double>(ResidentialValues),
StackMode = StackMode.Values, // this is not necessary, values is the default stack mode
DataLabels = true
},
new StackedColumnSeries
{
Title = "Small Commercial Indust",
Values = new ChartValues<double>(SmallCommercialIndustValues),
StackMode = StackMode.Values,
DataLabels = true
}
};
Labels = AnalystName.ToArray();
//Formatter = value => value + " Disputes";
DataContext = this;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public SeriesCollection SeriesCollection { get; set; }
public string[] Labels { get; set; }
public Func<double, string> Formatter { get; set; }
private void butn_ExecuteQuery_Click(object sender, RoutedEventArgs e)
{
// Refresh Chart
ChartValues();
}

在调用ChartValues()或实现INotifyPropertyChanged并从源属性的setter引发PropertyChanged事件之前设置DataContext = null;

最好不要只为更新某些属性的数据绑定而重置DataContext。这将导致性能非常差,因为整个视图将被迫再次渲染。DataContext也是从元素树向下继承的
更好地编写更干净的代码,更优雅地处理动态数据,并符合框架的要求(请参阅数据绑定概述(。

在控件内部(或通常在DependencyObject上(,您应该始终将数据绑定中涉及的所有属性实现为DependencyProperty
它们将自动刷新目标,并根据Binding.Mode以及特定Binding的来源
由于您正在重新分配SeriesCollectionLabels,因此这两个属性都应该是DependencyProperty

在您的情况下,您可以不实现依赖属性,因为您只是在更新集合。因此,只需避免在每次刷新时重新分配新集合,而是在实现INotifyCollectionChanged的集合上使用IList.ClearIList.Add

SeriesCollection已经实现了INotifyCollectionChanged,所以您只需要将Labels属性的类型从string[]更改为ObservableCollection<string>。通过这种方式,IList.ClearIList.Add操作将由绑定目标(图表控件(自动反映:

public SeriesCollection SeriesCollection { get; set; }
public ObservableCollection<string> Labels { get; set; }
public HBDBreakdown()
{
InitializeComponent();

// Set the `DataContext` once in the constructor
this.DataContext = this;
// Initialize the collection to prepare them for dynamic clear/add
this.SeriesCollection = new SeriesCollection();
this.Labels = new ObservableCollection<string>();
}
private void ChartValues()
{
try
{
...
this.SeriesCollection.Clear();
this.SeriesCollection.Add(
new StackedColumnSeries
{
Title = "Residential",
Values = new ChartValues<double>(ResidentialValues),
StackMode = StackMode.Values, // this is not necessary, values is the default stack mode
DataLabels = true
});
this.SeriesCollection.Add(
new StackedColumnSeries
{
Title = "Small Commercial Indust",
Values = new ChartValues<double>(SmallCommercialIndustValues),
StackMode = StackMode.Values,
DataLabels = true
});
this.Labels.Clear();
AnalystName.ForEach(this.Labels.Add);
}
// Code smell: never catch 'Exception'. 
// Only catch explicitly those exception you can handle.
// A user can't handle exceptions, so in a real business application you wouldn't show the exception message to the user.
catch (Exception ex)
{
// Bad practice
MessageBox.Show(ex.Message);
}
}

另请阅读:异常和异常处理,特别是异常概述和异常设计指南。

最新更新