Hello. First, I apologize for the fact that I can seem somewhat intrusive. I want to use RadTileView for real-time charts displaying. For example, if I need the folowing RadCartesianChart (please see 'SensorsSignals.PNG' file attached and XAML markup below)
<
telerik:RadCartesianChart
x:Name
=
"chart1"
HorizontalAlignment
=
"Stretch"
VerticalAlignment
=
"Stretch"
EmptyContent
=
"{Binding ChartEmptyContent}"
>
<!--Turn scrollbar visualization off-->
<
telerik:RadCartesianChart.Resources
>
<
Style
TargetType
=
"telerik:PanZoomBar"
>
<
Setter
Property
=
"Visibility"
Value
=
"Collapsed"
/>
</
Style
>
</
telerik:RadCartesianChart.Resources
>
<!--X axis-->
<
telerik:RadCartesianChart.HorizontalAxis
>
<
telerik:CategoricalAxis
LabelInterval
=
"6"
/>
</
telerik:RadCartesianChart.HorizontalAxis
>
<!--Y axis-->
<
telerik:RadCartesianChart.VerticalAxis
>
<
telerik:LinearAxis
Minimum
=
"-128"
Maximum
=
"127"
MajorStep
=
"8"
/>
</
telerik:RadCartesianChart.VerticalAxis
>
<!--Chart curve itself-->
<
telerik:SplineSeries
CategoryBinding
=
"Item1"
ValueBinding
=
"Item2"
ItemsSource
=
"{Binding SensorData}"
Style
=
"{StaticResource SplineSeriesStyle}"
/>
<!--Layout grid-->
<
telerik:RadCartesianChart.Grid
>
<
telerik:CartesianChartGrid
MajorLinesVisibility
=
"XY"
StripLinesVisibility
=
"XY"
IsTabStop
=
"False"
>
<
telerik:CartesianChartGrid.YStripeBrushes
>
<
SolidColorBrush
Color
=
"#FFD7D7D7"
Opacity
=
"0.3"
/>
<
SolidColorBrush
Color
=
"Transparent"
/>
</
telerik:CartesianChartGrid.YStripeBrushes
>
<
telerik:CartesianChartGrid.XStripeBrushes
>
<
SolidColorBrush
Color
=
"#FFD7D7D7"
Opacity
=
"0.3"
/>
<
SolidColorBrush
Color
=
"Transparent"
/>
</
telerik:CartesianChartGrid.XStripeBrushes
>
</
telerik:CartesianChartGrid
>
</
telerik:RadCartesianChart.Grid
>
<!--Behaviors of the chart-->
<
telerik:RadCartesianChart.Behaviors
>
<
telerik:ChartPanAndZoomBehavior
DragMode
=
"Pan"
ZoomMode
=
"Both"
PanMode
=
"Both"
/>
</
telerik:RadCartesianChart.Behaviors
>
</
telerik:RadCartesianChart
>
According to your 'DataBinding_WPF' program example and 'Data Binding' paper in http://docs.telerik.com/devtools/wpf/controls/radtileview/populating-with-data/populating-binding-to-collection I do the folowing steps.
1) In the View I write such markup:
<
UserControl
x:Class
=
"UltrasonicSensors.Views.UltrasonicSensorsView"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
xmlns:prism
=
"http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel
=
"True"
>
<
FrameworkElement.Resources
>
<!--Curve thickness and color style-->
<
Style
x:Key
=
"SplineSeriesStyle"
TargetType
=
"telerik:SplineSeries"
BasedOn
=
"{StaticResource SplineSeriesStyle}"
>
<
Setter
Property
=
"Stroke"
Value
=
"RoyalBlue"
/>
<
Setter
Property
=
"StrokeThickness"
Value
=
"3"
/>
</
Style
>
<
DataTemplate
x:Key
=
"ItemTemplate"
>
<
TextBlock
Text
=
"{Binding ChartCaption}"
/>
</
DataTemplate
>
<!--Template of sensor signal chart-->
<
DataTemplate
x:Key
=
"ContentTemplate"
>
<
telerik:RadCartesianChart
x:Name
=
"chart1"
HorizontalAlignment
=
"Stretch"
VerticalAlignment
=
"Stretch"
EmptyContent
=
"{Binding ChartEmptyContent}"
>
<!--Turn scrollbars off-->
<
telerik:RadCartesianChart.Resources
>
<
Style
TargetType
=
"telerik:PanZoomBar"
>
<
Setter
Property
=
"Visibility"
Value
=
"Collapsed"
/>
</
Style
>
</
telerik:RadCartesianChart.Resources
>
<!--X axis-->
<
telerik:RadCartesianChart.HorizontalAxis
>
<
telerik:CategoricalAxis
LabelInterval
=
"6"
/>
</
telerik:RadCartesianChart.HorizontalAxis
>
<!--Y axis-->
<
telerik:RadCartesianChart.VerticalAxis
>
<
telerik:LinearAxis
Minimum
=
"-128"
Maximum
=
"127"
MajorStep
=
"8"
/>
</
telerik:RadCartesianChart.VerticalAxis
>
<!--Chart curve itself-->
<
telerik:SplineSeries
CategoryBinding
=
"Item1"
ValueBinding
=
"Item2"
ItemsSource
=
"{Binding SensorData}"
Style
=
"{StaticResource SplineSeriesStyle}"
/>
<!--Layout grid-->
<
telerik:RadCartesianChart.Grid
>
<
telerik:CartesianChartGrid
MajorLinesVisibility
=
"XY"
StripLinesVisibility
=
"XY"
IsTabStop
=
"False"
>
<
telerik:CartesianChartGrid.YStripeBrushes
>
<
SolidColorBrush
Color
=
"#FFD7D7D7"
Opacity
=
"0.3"
/>
<
SolidColorBrush
Color
=
"Transparent"
/>
</
telerik:CartesianChartGrid.YStripeBrushes
>
<
telerik:CartesianChartGrid.XStripeBrushes
>
<
SolidColorBrush
Color
=
"#FFD7D7D7"
Opacity
=
"0.3"
/>
<
SolidColorBrush
Color
=
"Transparent"
/>
</
telerik:CartesianChartGrid.XStripeBrushes
>
</
telerik:CartesianChartGrid
>
</
telerik:RadCartesianChart.Grid
>
<!--Behaviors-->
<
telerik:RadCartesianChart.Behaviors
>
<
telerik:ChartPanAndZoomBehavior
DragMode
=
"Pan"
ZoomMode
=
"Both"
PanMode
=
"Both"
/>
</
telerik:RadCartesianChart.Behaviors
>
</
telerik:RadCartesianChart
>
</
DataTemplate
>
</
FrameworkElement.Resources
>
<
Grid
>
<!--Sensors signals charts:-->
<
telerik:RadTileView
x:Name
=
"xTileView"
Grid.Row
=
"0"
Grid.Column
=
"0"
PreservePositionWhenMaximized
=
"True"
MinimizedColumnWidth
=
"150"
ItemTemplate
=
"{StaticResource ItemTemplate}"
ContentTemplate
=
"{StaticResource ContentTemplate}"
ItemsSource
=
"{Binding SensorSignalCharts}"
>
</
telerik:RadTileView
>
</
Grid
>
</
UserControl
>
In the ViewModel I write something similar to the following code in C# (note!!! this code here for STUBS but not for real ultrasonic signals!!!):
/// <summary>
/// ViewModel of charts of STUBS for signals of ultrasonic sensors.
/// </summary>
public
class
UltrasonicSensorsViewModel : BindableBase, IConfirmNavigationRequest
{
#region Fields
#region Constant Fields
/// <summary>
/// Message about mising of chart data.
/// </summary>
private
const
string
NO_DATA_FOR_CHART =
"Нет данных для построения графика"
;
/// <summary>
/// Number of points to build a chart.
/// </summary>
private
const
int
CHART_POINTS_QUANTITY = 180;
#endregion
#region Common Variable Fields
/// <summary>
/// Collection of View Models of sensor signal chart.
/// </summary>
private
RadObservableCollection<SensorSignalChartViewModel> _sensorSignalCharts;
#endregion
#endregion
#region Constructors
public
UltrasonicSensorsViewModel()
{
// Data for constructing a sinusoidal STUB chart.
byte
[] aDummyData = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x01, 0x00, 0x00, 0xFE, 0xFE, 0xFF, 0x00, 0x01, 0x03, 0x02, 0x01, 0x00, 0xFD, 0xFC, 0xFD, 0x00, 0x04, 0x06, 0x07, 0x03, 0xFD, 0xF7, 0xF3, 0xF6,
0x00, 0x0B, 0x14, 0x15, 0x0C, 0xFC, 0xEA, 0xDF, 0xE2, 0xF4, 0x0E, 0x26, 0x2F, 0x24, 0x07, 0xE4, 0xCA, 0xC6, 0xDB, 0x01, 0x2B, 0x44, 0x41, 0x22,
0xF3, 0xC8, 0xB4, 0xBF, 0xE6, 0x18, 0x41, 0x4E, 0x3B, 0x10, 0xE0, 0xBE, 0xB8, 0xCF, 0xF9, 0x23, 0x3E, 0x3E, 0x26, 0x01, 0xDF, 0xCD, 0xCF, 0xE5,
0x01, 0x1A, 0x27, 0x23, 0x13, 0x00, 0xEF, 0xE7, 0xE9, 0xF2, 0xFE, 0x08, 0x0D, 0x0E, 0x0B, 0x06, 0x01, 0xFD, 0xF9, 0xF6, 0xF6, 0xF8, 0xFD, 0x03,
0x0A, 0x0E, 0x0D, 0x07, 0xFF, 0xF5, 0xF0, 0xF0, 0xF7, 0x00, 0x0A, 0x10, 0x0E, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// Create the collection of View Models of sensor signal chart.
this
.SensorSignalCharts =
new
RadObservableCollection<SensorSignalChartViewModel>();
// Create array of chart points.
Tuple<
int
,
double
>[] aSensorData =
new
Tuple<
int
,
double
>[CHART_POINTS_QUANTITY];
sbyte
[] aSignedDummyData = Array.ConvertAll(aDummyData, b =>
unchecked
((
sbyte
)b));
for
(
int
i = 0; i < aSignedDummyData.Length; i++)
aSensorData[i] =
new
Tuple<
int
,
double
>(i, aSignedDummyData[i]);
// Populate all displayed charts with data.
SensorSignalChartViewModel sscm =
new
SensorSignalChartViewModel(aSensorData);
sscm.ChartCaption =
"График сигнала от первого сенсора"
;
sscm.ChartEmptyContent = NO_DATA_FOR_CHART;
this
.SensorSignalCharts.Add(sscm);
sscm =
new
SensorSignalChartViewModel(aSensorData);
sscm.ChartCaption =
"График сигнала от второго сенсора"
;
sscm.ChartEmptyContent = NO_DATA_FOR_CHART;
this
.SensorSignalCharts.Add(sscm);
sscm =
new
SensorSignalChartViewModel(aSensorData);
sscm.ChartCaption =
"График сигнала от третьего сенсора"
;
sscm.ChartEmptyContent = NO_DATA_FOR_CHART;
this
.SensorSignalCharts.Add(sscm);
sscm =
new
SensorSignalChartViewModel(aSensorData);
sscm.ChartCaption =
"График сигнала от четвёртого сенсора"
;
sscm.ChartEmptyContent = NO_DATA_FOR_CHART;
this
.SensorSignalCharts.Add(sscm);
sscm =
new
SensorSignalChartViewModel(aSensorData);
sscm.ChartCaption =
"График сигнала от пятого сенсора"
;
sscm.ChartEmptyContent = NO_DATA_FOR_CHART;
this
.SensorSignalCharts.Add(sscm);
sscm =
new
SensorSignalChartViewModel(aSensorData);
sscm.ChartCaption =
"График сигнала от шестого сенсора"
;
sscm.ChartEmptyContent = NO_DATA_FOR_CHART;
this
.SensorSignalCharts.Add(sscm);
sscm =
new
SensorSignalChartViewModel(aSensorData);
sscm.ChartCaption =
"График сигнала от седьмого сенсора"
;
sscm.ChartEmptyContent = NO_DATA_FOR_CHART;
this
.SensorSignalCharts.Add(sscm);
sscm =
new
SensorSignalChartViewModel(aSensorData);
sscm.ChartCaption =
"График сигнала от восмого сенсора"
;
sscm.ChartEmptyContent = NO_DATA_FOR_CHART;
this
.SensorSignalCharts.Add(sscm);
}
#endregion
#region Properties
/// <summary>
/// Gets or sets Collection of View Models of sensor signal chart.
/// </summary>
public
RadObservableCollection<SensorSignalChartViewModel> SensorSignalCharts
{
get
{
return
this
._sensorSignalCharts; }
set
{
this
.SetProperty(
ref
this
._sensorSignalCharts, value); }
}
#endregion
}
All works OK here. BUT. If I need to locate inside the block of
<
FrameworkElement.Resources
>
. . . . . . . . . . . . . . . . . .
</
FrameworkElement.Resources
>
a XAML markup which contains <UserControl.Resources>...</UserControl.Resources> blocks and <i:Interaction.Triggers>...</i:Interaction.Triggers> blocks then how WPF will behave itself in this case? Will she allow such markup or not? As far as I know, it's impossible to place one <.Resource> tag inside another <.Resource> tag. So, what I can do in this case? Below is XAML markup which I need to locate inside <FrameworkElement.Resource></FrameworkElement.Resource> tag. For clarity, I show it inside <UserControl></UserControl> tag as I've done it in the application.
<
UserControl
x:Class
=
"DeviceReading.Views.t_GasVelocityPerBeamView"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
xmlns:prism
=
"http://prismlibrary.com/"
xmlns:local
=
"clr-namespace:DeviceReading"
xmlns:views
=
"clr-namespace:DeviceReading.Views"
xmlns:commonControls
=
"clr-namespace:CommonWpfControlLibrary;assembly=CommonWpfControlLibrary"
prism:ViewModelLocator.AutoWireViewModel
=
"True"
>
<
UserControl.Resources
>
<
telerik:ChartPalette
x:Key
=
"customPalette"
>
<
telerik:ChartPalette.SeriesEntries
>
<
telerik:PaletteEntryCollection
SeriesFamily
=
"Line"
>
<
telerik:PaletteEntry
Fill
=
"Blue"
Stroke
=
"Blue"
/>
<
telerik:PaletteEntry
Fill
=
"Crimson"
Stroke
=
"Crimson"
/>
<
telerik:PaletteEntry
Fill
=
"Green"
Stroke
=
"Green"
/>
<
telerik:PaletteEntry
Fill
=
"DarkOrange"
Stroke
=
"DarkOrange"
/>
<
telerik:PaletteEntry
Fill
=
"Purple"
Stroke
=
"Purple"
/>
<
telerik:PaletteEntry
Fill
=
"DarkTurquoise"
Stroke
=
"DarkTurquoise"
/>
<
telerik:PaletteEntry
Fill
=
"SaddleBrown"
Stroke
=
"SaddleBrown"
/>
<
telerik:PaletteEntry
Fill
=
"SlateBlue"
Stroke
=
"SlateBlue"
/>
</
telerik:PaletteEntryCollection
>
</
telerik:ChartPalette.SeriesEntries
>
</
telerik:ChartPalette
>
<
local:StringToLegendSettingsConverter
x:Key
=
"StringToLegendSettingsConverter"
/>
</
UserControl.Resources
>
<
i:Interaction.Triggers
>
<!--OK notification dialog-->
<
prism:InteractionRequestTrigger
SourceObject
=
"{Binding NotificationRequest, Mode=OneWay}"
>
<
prism:PopupWindowAction
IsModal
=
"True"
CenterOverAssociatedObject
=
"True"
>
<
prism:PopupWindowAction.WindowContent
>
<
commonControls:NotificationDialogPopupView
/>
</
prism:PopupWindowAction.WindowContent
>
<
prism:PopupWindowAction.WindowStyle
>
<
Style
TargetType
=
"Window"
>
<
Setter
Property
=
"ResizeMode"
Value
=
"NoResize"
/>
<
Setter
Property
=
"SizeToContent"
Value
=
"WidthAndHeight"
/>
</
Style
>
</
prism:PopupWindowAction.WindowStyle
>
</
prism:PopupWindowAction
>
</
prism:InteractionRequestTrigger
>
. . . . . . . . . . . . . . . . . . . . . . . . . . .
</
i:Interaction.Triggers
>
<
Grid
>
<!--Menu displayed when user clicks right mouse button-->
<
telerik:RadContextMenu.ContextMenu
>
<
telerik:RadContextMenu
>
<
telerik:RadMenuItem
Header
=
"Show Bar Chart"
IsCheckable
=
"True"
IsChecked
=
"{Binding IsBarChartSelected, Mode=TwoWay}"
Command
=
"{Binding ShowBarChartCommand}"
/>
<
telerik:RadMenuItem
Header
=
"Show Curve Splne Chart"
IsCheckable
=
"True"
IsChecked
=
"{Binding IsSplineChartSelected, Mode=TwoWay}"
Command
=
"{Binding ShowSplineChartCommand}"
/>
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
</
telerik:RadContextMenu
>
</
telerik:RadContextMenu.ContextMenu
>
<!--Bar chart of gas velocity value on each ultrasonic beam-->
<
telerik:RadCartesianChart
Visibility
=
"{Binding IsAbsoluteBarChartVisible}"
>
<!--X axis-->
<
telerik:RadCartesianChart.HorizontalAxis
>
<
telerik:CategoricalAxis
/>
</
telerik:RadCartesianChart.HorizontalAxis
>
<!--Y axis---->
<
telerik:RadCartesianChart.VerticalAxis
>
<
telerik:LinearAxis
Title
=
"Метры в секунду [м/с]"
Minimum
=
"{Binding ChartMinimum}"
Maximum
=
"{Binding ChartMaximum}"
MajorStep
=
"{Binding CurrentStep}"
/>
</
telerik:RadCartesianChart.VerticalAxis
>
<!--Bar chart itself-->
<
telerik:RadCartesianChart.Series
>
<
telerik:BarSeries
ShowLabels
=
"True"
CategoryBinding
=
"Category"
ValueBinding
=
"Value"
ItemsSource
=
"{Binding Data}"
/>
</
telerik:RadCartesianChart.Series
>
</
telerik:RadCartesianChart
>
<!--Visualizer of colors of all curves in the curve chart of gas velocity value on each ultrasonic beam-->
<
telerik:RadLegend
Grid.Column
=
"1"
Items
=
"{Binding LegendItems, ElementName=splineAbsoluteChart}"
HorizontalAlignment
=
"Right"
VerticalAlignment
=
"Top"
Visibility
=
"{Binding IsAbsoluteSplineChartVisible}"
/>
<!--Curve spline chart of gas velocity value on each ultrasonic beam-->
<
telerik:RadCartesianChart
x:Name
=
"splineAbsoluteChart"
Visibility
=
"{Binding IsAbsoluteSplineChartVisible}"
Palette
=
"{StaticResource customPalette}"
>
<!--Turn scrollbars off-->
<
telerik:RadCartesianChart.Resources
>
<
Style
TargetType
=
"telerik:PanZoomBar"
>
<
Setter
Property
=
"Visibility"
Value
=
"Collapsed"
/>
</
Style
>
</
telerik:RadCartesianChart.Resources
>
<!--X axis-->
<
telerik:RadCartesianChart.HorizontalAxis
>
<
telerik:DateTimeContinuousAxis
MajorStepUnit
=
"Second"
LabelInterval
=
"5"
LabelFormat
=
"hh:mm:ss"
FontFamily
=
"Segoe UI"
PlotMode
=
"OnTicks"
TickOrigin
=
"{Binding AlignmentDate}"
/>
</
telerik:RadCartesianChart.HorizontalAxis
>
<!--Y axis-->
<
telerik:RadCartesianChart.VerticalAxis
>
<
telerik:LinearAxis
FontFamily
=
"Segoe UI"
Title
=
"Метры в секунду [м/с]"
/>
</
telerik:RadCartesianChart.VerticalAxis
>
<!--Layout grid-->
<
telerik:RadCartesianChart.Grid
>
<
telerik:CartesianChartGrid
MajorLinesVisibility
=
"XY"
MajorXLineDashArray
=
"3,4"
MajorYLineDashArray
=
"3,4"
/>
</
telerik:RadCartesianChart.Grid
>
<!--Series provider of curves-->
<
telerik:RadCartesianChart.SeriesProvider
>
<
telerik:ChartSeriesProvider
Source
=
"{Binding SeriesData}"
>
<
telerik:ChartSeriesProvider.SeriesDescriptors
>
<
telerik:CategoricalSeriesDescriptor
CategoryPath
=
"Category"
ValuePath
=
"Value"
ItemsSourcePath
=
"ChartPoints"
>
<
telerik:CategoricalSeriesDescriptor.TypeConverter
>
<
local:SeriesTypeConverter
/>
</
telerik:CategoricalSeriesDescriptor.TypeConverter
>
<
telerik:CategoricalSeriesDescriptor.Style
>
<
Style
TargetType
=
"telerik:SplineSeries"
BasedOn
=
"{StaticResource SplineSeriesStyle}"
>
<
Setter
Property
=
"LegendSettings"
Value
=
"{Binding SeriesName, Converter={StaticResource StringToLegendSettingsConverter}}"
/>
</
Style
>
</
telerik:CategoricalSeriesDescriptor.Style
>
</
telerik:CategoricalSeriesDescriptor
>
</
telerik:ChartSeriesProvider.SeriesDescriptors
>
</
telerik:ChartSeriesProvider
>
</
telerik:RadCartesianChart.SeriesProvider
>
<!--Behaviors-->
<
telerik:RadCartesianChart.Behaviors
>
<
telerik:ChartPanAndZoomBehavior
DragMode
=
"Pan"
ZoomMode
=
"Both"
PanMode
=
"Both"
/>
</
telerik:RadCartesianChart.Behaviors
>
<!--Mapping events handling to the ViewModel-->
<
telerik:EventToCommandBehavior.EventBindings
>
<
telerik:EventBinding
Command
=
"{Binding ShowHistoricalChartCommand}"
EventName
=
"PreviewMouseDoubleClick"
RaiseOnHandledEvents
=
"True"
PassEventArgsToCommand
=
"True"
/>
</
telerik:EventToCommandBehavior.EventBindings
>
</
telerik:RadCartesianChart
>
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
</
Grid
>
</
UserControl
>
If you'd like you can see gas velocity bar chart in 'GasVelocityBarChart.PNG' file attached. And you can see gas velocity spline chart in 'GasVelocitySplineChart.PNG' file attached.
So, I'm very interested in the following thing: How to put the content (that is inside the <UserControl></UserControl> tag in the figure above) into <FrameworkElement.Resources></FrameworkElement.Resources> tag? After all, this inserted content itself has in its composition the <UserControl.Resources>...</UserControl.Resources> and <i:Interaction.Triggers>...</i:Interaction.Triggers> tags. Please help me understand this. I will be very grateful to you for your help because I really appreciate your help.