Hi, I want to have RadTimeBar with different kind of content. So I have the following xaml (part of the user control):
<
telerik:RadTimeBar
Margin
=
"3"
x:Name
=
"Timebar"
IsEnabled
=
"{Binding IsTimeSelectionEnabled}"
Grid.Row
=
"1"
VerticalAlignment
=
"Top"
Height
=
"90"
HorizontalAlignment
=
"Stretch"
PeriodStart
=
"{Binding PeriodStart, Mode=TwoWay}"
PeriodEnd
=
"{Binding PeriodEnd, Mode=TwoWay}"
VisiblePeriodStart
=
"{Binding VisiblePeriodStart, Mode=TwoWay}"
VisiblePeriodEnd
=
"{Binding VisiblePeriodEnd, Mode=TwoWay}"
SelectionStart
=
"{Binding SelectionStart, Mode=TwoWay}"
SelectionEnd
=
"{Binding SelectionEnd, Mode=TwoWay}"
>
<
i:Interaction.Triggers
>
<
i:EventTrigger
EventName
=
"SelectionChanged"
>
<
i:InvokeCommandAction
Command
=
"{Binding ApplyPeriodCommand}"
/>
</
i:EventTrigger
>
</
i:Interaction.Triggers
>
<
telerik:RadTimeBar.Intervals
>
<
telerik:MonthInterval
/>
<
telerik:WeekInterval
/>
<
telerik:DayInterval
/>
<
telerik:HourInterval
/>
</
telerik:RadTimeBar.Intervals
>
</
telerik:RadTimeBar
>
The content is set as follows in the code behind:
public
FrameworkElement TimeBarContent
{
get
{
return
this
.Timebar.Content
as
FrameworkElement; }
set
{
this
.Timebar.Content = value;
}
}
public
TimeLineControl()
{
InitializeComponent();
this
.DataContextChanged += TimeLineControl_DataContextChanged;
}
void
TimeLineControl_DataContextChanged(
object
sender, DependencyPropertyChangedEventArgs e)
{
if
(
this
.TimeBarContent ==
null
)
return
;
var timeLineViewModel = e.NewValue
as
TimeLineViewModel;
if
(timeLineViewModel !=
null
)
this
.TimeBarContent.DataContext = timeLineViewModel.TimeBarContentDataContext;
}
The SparkLine control, which is set as content of time line is:
<UserControl x:Class=
"Wave.Platform.PortalFramework.Infrastructure.Controls.Views.SparkLineControl"
xmlns:telerik=
"clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.DataVisualization"
xmlns:viewModels=
"clr-namespace:Wave.Platform.PortalFramework.Infrastructure.Controls.ViewModels"
mc:Ignorable=
"d"
d:DesignHeight=
"300"
d:DesignWidth=
"400"
>
<d:DesignData.DataContext>
<viewModels:SparklineControlViewModel/>
</d:DesignData.DataContext>
<telerik:RadColumnSparkline Name=
"SparkLine"
ItemsSource=
"{Binding SparklineData}"
Margin=
"0,0,0,5"
ColumnWidthPercent=
"0.8"
XValuePath=
"Moment"
YValuePath=
"Value"
MaxYValue=
"{Binding Maximum}"
AutoRange=
"False"
/>
</UserControl>
The view model of the sparkline is as follows
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public
class
SparklineControlViewModel : NotificationObject, ITimeBarContentDataContext
{
private
double
_maximum;
public
double
Maximum
{
get
{
return
_maximum; }
private
set
{
_maximum = value;
RaisePropertyChanged(()=>
this
.Maximum);
}
}
private
TimeSpan _groupingTimeSpan;
public
TimeSpan GroupingTimeSpan
{
get
{
return
_groupingTimeSpan; }
set
{
_groupingTimeSpan = value;
RaisePropertyChanged(() =>
this
.GroupingTimeSpan);
}
}
private
ObservableCollection<ColumnSparklineVM> _sparklineData =
new
ObservableCollection<ColumnSparklineVM>();
public
ObservableCollection<ColumnSparklineVM> SparklineData
{
get
{
return
_sparklineData; }
private
set
{
_sparklineData = value;
RaisePropertyChanged(()=>
this
.SparklineData);
}
}
public
SparklineControlViewModel()
{
}
public
void
SetData(IEnumerable<IDataWithMoment> data)
{
this
.SparklineData.Clear();
var dataWithMoments = data
as
IList<IDataWithMoment> ?? data.ToList();
if
(!dataWithMoments.Any())
return
;
var groupedTimes = dataWithMoments.GroupBy(dt => dt.Moment.Ticks/
this
.GroupingTimeSpan.Ticks);
this
.SparklineData = groupedTimes.Select(g =>
new
ColumnSparklineVM() { Moment =
new
DateTime(g.Key * GroupingTimeSpan.Ticks), Value = g.Count() }).ToObservable();
SetMaximum();
}
public
void
SetData(IEnumerable<ColumnSparklineVM> data)
{
this
.SparklineData = data.ToObservable();
SetMaximum();
}
private
void
SetMaximum()
{
this
.Maximum = Math.Max(Maximum, SparklineData.Max(s => s.Value));
}
}
public
class
ColumnSparklineVM : NotificationObject
{
private
double
_value;
public
double
Value
{
get
{
return
_value; }
set
{
_value = value;
RaisePropertyChanged(()=>
this
.Value);
}
}
private
DateTime _moment;
public
DateTime Moment
{
get
{
return
_moment; }
set
{
_moment = value;
RaisePropertyChanged(()=>
this
.Moment);
}
}
}
public
interface
IDataWithMoment
{
DateTime Moment {
get
; }
}
Add some test data are inserted this way:
if
(SparklineControlViewModel !=
null
)
{
for
(
int
i = 0; i < 1000; i++)
{
ReportsBasic.Add(
new
DetailedReportBasic(){FirstLogicCause =
new
LogicCause(){ActivatedUtc = DateTime.Now.AddMinutes(-i)}});
}
SparklineControlViewModel.SetData(
this
.ReportsBasic);
}
The TimeSpan of is set to One hour , wo when grouped the passed data to SetData() method create 17 SparklineData objects with moments - 17 hours which are added to the ItemsSource of the SparkLine control. However the columns drawn seems to be with completely different timestamps as you can see on the attached screen shot - the 17 columns spread for several days each...
Please tell me what am I missing? I guess it is some king syncronisation between the sparkline and the timebar, but no such is needed in some of the samples I can see in the telerik demos...
Thank you in advance for your help!