I'm using the RadCartesianChart to display a dynamic number of series in a lineseries and am trying to get it to refresh automatically when the collection that drives the ChartSeriesProvider is changed. I am using the MVVM pattern.
This is the XAML defining my charts.
<
chart:RadCartesianChart
Grid.Column
=
"0"
Grid.Row
=
"0"
x:Name
=
"ColumnChart"
>
<
chart:RadCartesianChart.HorizontalAxis
>
<
chartView:CategoricalAxis
Title
=
"Date"
/>
</
chart:RadCartesianChart.HorizontalAxis
>
<
chart:RadCartesianChart.VerticalAxis
>
<
chartView:LinearAxis
Title
=
"Value"
/>
</
chart:RadCartesianChart.VerticalAxis
>
<
chart:RadCartesianChart.Behaviors
>
<
chartView:ChartTooltipBehavior
Placement
=
"Top"
VerticalOffset
=
"20"
/>
<
chartView:ChartPanAndZoomBehavior
ZoomMode
=
"Both"
/>
</
chart:RadCartesianChart.Behaviors
>
<
chart:RadCartesianChart.SeriesProvider
>
<
chartView:ChartSeriesProvider
IsDynamicSeries
=
"True"
Source
=
"{Binding FilteredSeries}"
>
<
chartView:ChartSeriesProvider.SeriesDescriptors
>
<
chartView:CategoricalSeriesDescriptor
ItemsSourcePath
=
"Values"
CategoryPath
=
"Date"
ValuePath
=
"Value"
>
<
chartView:CategoricalSeriesDescriptor.Style
>
<
Style
TargetType
=
"chartView:LineSeries"
>
<
Setter
Property
=
"StrokeThickness"
Value
=
"2"
/>
<
Setter
Property
=
"PointTemplate"
Value
=
"{StaticResource PointTemplate}"
/>
</
Style
>
</
chartView:CategoricalSeriesDescriptor.Style
>
</
chartView:CategoricalSeriesDescriptor
>
</
chartView:ChartSeriesProvider.SeriesDescriptors
>
</
chartView:ChartSeriesProvider
>
</
chart:RadCartesianChart.SeriesProvider
>
</
chart:RadCartesianChart
>
This is the View model driving the chart.
public
class
PostProcessingColumnChartViewModel : INotifyPropertyChanged
{
private
ObservableCollection<ChartSeries> _series;
private
ObservableCollection<
long
> _availableLineNumbers;
private
long
_selectedLineNumber = -1;
public
PostProcessingColumnChartViewModel(PostProcessingEntry entry)
{
Name = entry.Name;
AvailableLineNumbers.Add(-1);
foreach
(var postProcessingRecord
in
entry.Records)
{
if
(!postProcessingRecord.Value.LineNumber.HasValue)
continue
;
var series =
new
ChartSeries()
{
SerialNumber = postProcessingRecord.Value.SerialNumber,
LineNumber = postProcessingRecord.Value.LineNumber,
PointNumber = postProcessingRecord.Value.StationNumber
};
foreach
(var value
in
postProcessingRecord.Value.Values)
{
series.Values.Add(
new
ChartRecord() {Date = value.Key, Value = value.Value});
}
Series.Add(series);
}
var lineNumbers = Series.Where(s => s.LineNumber.HasValue).Select(s => s.LineNumber.Value).Distinct().OrderBy(ln => ln).ToList();
foreach
(var lineNumber
in
lineNumbers)
{
AvailableLineNumbers.Add(lineNumber);
}
}
public
string
Name {
get
;
set
; }
public
ObservableCollection<ChartSeries> Series => _series ?? (_series =
new
ObservableCollection<ChartSeries>());
public
ObservableCollection<
long
> AvailableLineNumbers => _availableLineNumbers ?? (_availableLineNumbers =
new
ObservableCollection<
long
>());
public
ObservableCollection<ChartSeries> FilteredSeries =>
new
ObservableCollection<ChartSeries>(Series);
public
long
SelectedLineNumber
{
get
{
return
_selectedLineNumber; }
set
{
if
(_selectedLineNumber == value)
return
;
_selectedLineNumber = value;
OnPropertyChanged();
}
}
public
event
PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected
virtual
void
OnPropertyChanged([CallerMemberName]
string
propertyName =
null
)
{
if
(propertyName !=
null
&& propertyName.Equals(
"SelectedLineNumber"
))
{
FilteredSeries.Clear();
if
(SelectedLineNumber > -1)
foreach
(var series
in
Series.Where(s => s.LineNumber == SelectedLineNumber))
{
FilteredSeries.Add(series);
}
else
foreach
(var series
in
Series)
{
FilteredSeries.Add(series);
}
}
PropertyChanged?.Invoke(
this
,
new
PropertyChangedEventArgs(propertyName));
}
}
I have these charts in a tab control and if I try and filter one it doesn't change until I view a different graph and then come back to the one I filtered. I know this is because chart goes through the rebinding process and updates but I would like that to happen while the user is currently viewing that chart. Everything seems to beworking except for the chart not updating until a rebinding occurs.
GridViewSelectColumn seems to be very slow when selecting a very large list of items. From the looks of it, it appears to be issuing a property changed notification for each item individually.
Is there a way to speed it up?
I read examples from docs.telerik.com, downloaded demos but they're often so long and i can not know what i need in them.
I only need make an item of a list to parent items in code behind. Do i need HierarchicalDataTemplate or RadTreeViewItem ?
_______ my code _______
public static HttpClient client = new HttpClient() ;
private void _ProductList()
{
var url = "api/Products/";
HttpResponseMessage response = client.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
var x = response.Content.ReadAsAsync<List<Product>>().Result;
Product allprod = new Product();
allprod.ProdID = 0;
allprod.Name
= " All Products";
x.Add(allprod);
myTreeView.ItemsSource = x;
myTreeView.DisplayMemberPath = "Name";
myTreeView.SelectedValuePath
= "ProdID";
// ....
}
else
{
MessageBox.Show("Error Code " + response.StatusCode +
" : Message -
" + response.ReasonPhrase);
}
}
__________
I tried RadTreeViewItem, but it doesn't have SelectedValuePath property.
- Items show Name and selected value is its ProdID
And it seems difficult to use HierarchicalDataTemplate in code behind (with me).
- With my code, i have "prod.png" and i need "need.png"
It's the best if you can edit code to me, please. Thank you.
__________
At last, i think demos (not only treeview) need a version classic-demo which is the most simple (except styles) with small data.
Example "First look" is really a big demo.
Hello,
I just ported my solution from .NET 3.5 to .NET 4.6.1 and updated Telerik from version 2012.2.912.35 to 2015.3.1104.5.
This code used to work fine, the setter of the property was called when the control lost focus:
<
telerik:RadNumericUpDown
Value
=
"{Binding UIExceeding, Mode=TwoWay}"
SmallChange
=
"0"
LargeChange
=
"0"
>
After the framework and Telerik was updated, the setter was never called anymore. To go back to how it used to work, I had to add UpdateSourceTrigger=LostFocus and UpdateValueEvent="PropertyChanged":
<
telerik:RadNumericUpDown
Value
=
"{Binding UIExceeding, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
SmallChange
=
"0"
LargeChange
=
"0"
UpdateValueEvent
=
"PropertyChanged"
>
Could you tell me what changed in between versions?
Thanks in advance
Hi,
I have problems when drag dropping inherited appointments from RadListBox to RadScheduleView. When the inherited class ProtocolChildAppointment (as below) is dropped from radListBox to scheduleview its a ProtocolAppointment class not the intented inherited class. I have tried to override Drop-function without success. Everything looks like its dropping a ProtocolChildAppointment in the ConvertTo, ConvertDraggedData and Drop -functions.
public class ProtocolAppointment : Appointment
{
public ProtocolAppointment()
: base()
{
}
// code...
public override IAppointment Copy()
{
var newAppointment = new ProtocolAppointment();
newAppointment.CopyFrom(this);
return newAppointment;
}
}
public class ProtocolChildAppointment : ProtocolAppointment
{
public ProtocolChildAppointment()
: base()
{
}
//code...
public override IAppointment Copy()
{
var newAppointment = new ProtocolChildAppointment();
newAppointment.CopyFrom(this);
return newAppointment;
}
}
class ProtocolScheduleViewDragDropBehavior : Telerik.Windows.Controls.ScheduleViewDragDropBehavior
{
public override IEnumerable<IOccurrence> ConvertDraggedData(object data)
{
if (DataObjectHelper.GetDataPresent(data, typeof(ProtocolAppointment), true))
{
return ((IEnumerable)DataObjectHelper.GetData(data, typeof(ProtocolAppointment), true)).OfType<IOccurrence>();
}
return base.ConvertDraggedData(data);
}
public override void Drop(Telerik.Windows.Controls.DragDropState state)
{
// here all stil looks like its dropping ProtocolChildAppointment
base.Drop(state);
}
}
class ProtocolAppointmentConverter : DataConverter
{
public override string[] GetConvertToFormats()
{
return new string[] { typeof(PetErpUIClient.ProtocolAppointment).AssemblyQualifiedName };
}
public override object ConvertTo(object data, string format)
{
if (DataObjectHelper.GetDataPresent(data, typeof(ProtocolAppointment), false))
{
var payload = (IEnumerable)DataObjectHelper.GetData(data, typeof(ProtocolAppointment), false);
if (payload != null)
{
List<PetErpUIClient.ProtocolAppointment> apps = new List<PetErpUIClient.ProtocolAppointment>();
apps.AddRange(payload.OfType<PetErpUIClient.ProtocolAppointment>());
return apps;
}
}
return null;
}
}
Hi,
I am using RadListBox with ContextMenu for an item,
on every right click (only on an item) i need
1. that the menu will be open only on the item (when i am clicking on free space on the list area, i don't want that the menu will open)
2. get the selected item to my viewModel
this is my code:
<telerik:RadListBox
ItemSource ="{Binding collection}" , SelectedItem="{Binding Selected2, mode =TwoWay}">
<teletik:RadContextMenu.ContextMenu>
<teletik:RadContextMenu>
<telerik:RadMenuItem Header="This menu is only for item" command="{Binding c}" CommandParamter="{Binding=selectedItem}"/>
</teletik:RadContextMenu.ContextMenu>
</teletik:RadContextMenu>