I was wondering, if there is a property I can bind to get the selected item.
I use the slice option and would like to fill the SideDrawers content according to the selected item.
<
chart:RadPieChart.Behaviors
>
<
chart:ChartSelectionBehavior
DataPointSelectionMode
=
"Single"
SeriesSelectionMode
=
"None"
/>
</
chart:RadPieChart.Behaviors
>
I know there is a SelectionChanged somethere, I was just wondering, if there is a property I can bind to instead.
Jannik
4 Answers, 1 is accepted
I played around a littlebit more and tried to add a command which fires when I select something.
Unfortunately something is not working as I thought. My "Command" is always NULL and thus will not get fire.
The XAML part:
<
chart:RadPieChart.Behaviors
>
<
behaviors:ChartSelectionWithCommandBehavior
DataPointSelectionMode
=
"Single"
SeriesSelectionMode
=
"None"
Command
=
"{Binding PieSelectionChangedCommand}"
/>
</
chart:RadPieChart.Behaviors
>
Here is my custom "ChartSelectionBehavior" implementation:
public
class
ChartSelectionWithCommandBehavior : ChartSelectionBehavior
{
public
static
readonly
BindableProperty CommandProperty =
BindableProperty.Create(
"Command"
,
typeof
(ICommand),
typeof
(ChartSelectionWithCommandBehavior),
null
);
public
static
readonly
BindableProperty InputConverterProperty =
BindableProperty.Create(
"Converter"
,
typeof
(IValueConverter),
typeof
(ChartSelectionWithCommandBehavior),
null
);
public
ChartSelectionWithCommandBehavior()
{
SelectionChanged += OnSelectionChanged;
}
~ChartSelectionWithCommandBehavior()
{
SelectionChanged -= OnSelectionChanged;
}
private
void
OnSelectionChanged(
object
sender, EventArgs e)
{
BindingContext =
null
;
if
(Command ==
null
)
{
return
;
}
var parameter = Converter.Convert(e,
typeof
(
object
),
null
,
null
);
if
(Command.CanExecute(parameter))
{
Command.Execute(parameter);
}
}
protected
override
void
OnBindingContextChanged()
{
base
.OnBindingContextChanged();
var i = 1;
}
public
ICommand Command
{
get
=> (ICommand)GetValue(CommandProperty);
set
=> SetValue(CommandProperty, value);
}
public
IValueConverter Converter
{
get
=> (IValueConverter)GetValue(InputConverterProperty);
set
=> SetValue(InputConverterProperty, value);
}
}
I think that the Command is null because in the OnSelectionChanged method the BindingContext is set to null. Once you remove that line, the command will be raised as desired.
You can get the selected data points from the SelectedPoints property of the behavior. From the DataPoint you can get the original item from the DataItem property.
object
selectedItem = selectionBehavior.SelectedPoints.FirstOrDefault()?.DataItem;
I hope you find this information helpful.
Regards,
Petar Marchev
Progress Telerik
I figured out, that the BindingContext doesn't appear to be set. It kinda is a bug.
You have to use some sort of hack like this, overiding the OnParentSet method and getting parents context for further usage.
public
class
ChartSelectionWithCommandBehavior : ChartSelectionBehavior
{
public
static
readonly
BindableProperty CommandProperty =
BindableProperty.Create(
"Command"
,
typeof
(Command<(
object
,EventArgs)>),
typeof
(ChartSelectionWithCommandBehavior));
public
static
readonly
BindableProperty InputConverterProperty =
BindableProperty.Create(
"Converter"
,
typeof
(IValueConverter),
typeof
(ChartSelectionWithCommandBehavior));
public
ChartSelectionWithCommandBehavior()
{
SelectionChanged += OnSelectionChanged;
}
~ChartSelectionWithCommandBehavior()
{
SelectionChanged -= OnSelectionChanged;
if
(Parent !=
null
)
{
Parent.BindingContextChanged -= ParentOnBindingContextChanged;
}
}
protected
override
void
OnParentSet()
{
base
.OnParentSet();
Parent.BindingContextChanged += ParentOnBindingContextChanged;
}
private
void
ParentOnBindingContextChanged(
object
sender, EventArgs eventArgs)
{
BindingContext = Parent?.BindingContext;
}
private
void
OnSelectionChanged(
object
sender, EventArgs e)
{
if
(Command ==
null
)
{
return
;
}
if
(Command.CanExecute((sender, e)))
{
Command.Execute((sender, e));
}
}
public
Command<(
object
, EventArgs)> Command
{
get
=> (Command<(
object
, EventArgs)>)GetValue(CommandProperty);
set
=> SetValue(CommandProperty, value);
}
public
IValueConverter Converter
{
get
=> (IValueConverter)GetValue(InputConverterProperty);
set
=> SetValue(InputConverterProperty, value);
}
}
Good luck for all the people that need such a workaround.
After a more thorough investigation I can confirm that you are correct and indeed there is a bug in the chart. The binding context does not seem to be propagated to the behavior in all cases. This prevents the Binding from kicking in and as a result the Command is null. I have logged this in our feedback portal where you can track its status.
After some consideration, the dev team agreed that right now the MVVM support for selected items is not very satisfactory. This is why I logged a feature request for implementing an option for achieving such a scenario in a more straightforward way.
I have updated your Telerik points as a sign of gratitude for letting us know of the issue and giving us an idea about how to improve our products. Let us know if you have any questions.
Regards,
Petar Marchev
Progress Telerik