Livecharts change default legend - wpf

Here is my problem.
I am using LiveCharts to display some data.
Everything fine until showing the legend which represents all the data displayed.
chart with legend
Is it possibile to show a legend based on for example color(Stroke) or DefaultGeometries?
Thanks in advance for your help,
Diego

I know this is a little late but I was looking to do something similar, so here is what I was able to come up with.
You would need to create a new collection and follow the example for Live Charts Energy Predictions.
First you need to set the LegendLocation="None" for the Chart
<wpf:CartesianChart Hoverable="False" DataTooltip="{x:Null}" DisableAnimations="True" LegendLocation="None" Series="{Binding AllSeries, ElementName=FastGraphRoot}">
New Legend Code (part that matters in .xaml):
<ListBox Name="ListBox" MinHeight="250" ItemsSource="{Binding AllSeriesGroupByName, ElementName=FastGraphRoot}" Panel.ZIndex="1" BorderThickness="0" Background="Transparent">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type wpf:LineSeries}">
<TextBlock Text="{Binding Title}"
Foreground="{Binding Stroke}"
FontSize="24"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
The Binded list would come from the original series but grouped, I have used a property for this:
private SeriesCollection _allSeriesGroupByName = new SeriesCollection();
public SeriesCollection AllSeriesGroupByName { get { return _allSeriesGroupByName; } set { _allSeriesGroupByName = value; OnPropertyChanged(); } }
you could fill it simply with this code(or anything else you think is faster):
var col = collection.GroupBy(g => ((LineSeries)g).Stroke).Select(p => p.First());
AllSeriesGroupByName = new SeriesCollection();
foreach (var c in col)
{
AllSeriesGroupByName.Add(c);
}

Related

Performance issue - DataTemplate and DataBinding - 1st load

Here a drawing of my UI:
I have a list of elements at the top (clickme1 and clickme2). Each of this element will have several information contained inside MyList that I want to display inside the customElement of the listbox.
Clickme1 is clicked by default. When I click on the Clickme2, the listbox is taking 2-3 seconds before updating the CustomElements by the information of the Clickme2. When I switch again, it's updating right away so the problem is visible only for the first click. CustomElement has a lot of different bindings to the Clickme element (images and texts).
Here my code:
public ObservableCollection<CustomClass> MyList { get; set; }
<ListBox x:Name="MyListBox"
ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible"
ItemsSource="{Binding MyList}">
<ListBox.ItemTemplate>
<DataTemplate>
<local:CustomElement x:Name="MyCustomElement"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" BorderBrush="Transparent" Background="Black">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
I tried to use the VirtualizingStackPanel instead of the WrapPanel but it did not improve anything.
Any help ?
When you repopulate the collection, are you assigning a new ObservableCollection? Or working on the existing one?
You should populate your collection "off-line" and then bind it. Or Google for an ObservableCollection derivative that supports "bulk insert". The standard ObservableCollection will send a UI update for every insert.
WRONG:
MyList.Clear();
MyList.Add(...);
RIGHT:
ObservableCollection<CustomClass> coll = new ...
coll.Add(...);
MyList = coll;

WPF subclass Control without adding logic, just to be able to customize style and template?

I'm searching for a good way to create style-able, reusable controls in WPF. For example, I've got a twitter feed that could look something like this (much simplified):
<ItemsControl ItemsSource={Binding tweets}>
<ItemsControl.DataTemplate>
<DataTemplate TargetType="tweet">
<StackPanel>
<Image Source="{Binding user.image}" />
<TextBlock Text="{Binding text}" />
</StackPanel>
</DataTemplate>
</ItemsControl.DataTemplate>
</ItemsControl>
To make this a reusable control, I could put this in a UserControl. But doing just that would make it impossible to change the way the image part is displayed for example.
So what I find myself doing now is creating a control for the user's image, like this:
public class UserImage : Control
{
// Empty class..
}
<Style TargetType="{x:Type UserImage}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type UserImage}">
<Image Source="{Binding}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
// The itemscontrol datatemplate now looks like this
<DataTemplate TargetType="tweet">
<StackPanel>
<UserImage DataContext="{Binding user.image}" />
<TextBlock Text="{Binding text}" />
</StackPanel>
</DataTemplate>
Now I could do something like this to customize the appearance of the user image:
<Style TargetType="{x:Type UserImage}" BasedOn="{StaticResource {x:Type UserImage}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type UserImage}">
<Ellipse>
<Ellipse.Fill>
<ImageBrush ImageSource="{Binding}">
</Ellipse.Fill>
</Ellipse>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Even though this works, it does feel a bit inefficient and well ... wrong to have to create an "empty" control for each and every component in the custom control. Is this the way to go, or is there a cleaner way?

ListBox with embedded CheckBox restricting one item to be checked

I have a ListBox containing an ItemTemplate made up of a StackPanel containing a CheckBox and a Label. I want to allow only one list item to be checked at a time. I am having trouble understanding how I can get this accomplished. Here is the XAML describing the listbox:
<ListBox Grid.Row="0"
Grid.Column="0"
Width="180"
HorizontalAlignment="Left"
x:Name="listboxPlayers"
ItemsSource="{Binding Players}"
SelectedItem="{Binding SelectedPlayer, Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsDefault, Mode=TwoWay}"
VerticalAlignment="Center"
Checked="CheckBox_Checked"
Unchecked="CheckBox_Unchecked"/>
<Label Content="{Binding Name}"
VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
A Player is defined as this:
public class Player
{
public string Name { get; set; }
public bool IsDefault { get; set; }
}
My list of Players is defined like this:
public ObservableCollection<Player> Players { get; private set; }
My SelectedPlayer is defined like this:
public static readonly DependencyProperty SelectedPlayerProperty =
DependencyProperty.Register("SelectedPlayer", typeof(Player), typeof(MainWindow),
new FrameworkPropertyMetadata());
public Player SelectedPlayer
{
get { return (Player)GetValue(SelectedPlayerProperty); }
set { SetValue(SelectedPlayerProperty, value); }
}
I haven't been able to find a post or question that can help me. I've played with using a Checked event handler for the CheckBox but I can't seem to wrap my head around how I can relate the list to the correct Player in the list because the ListBox doesn't adjust the SelectedPlayer when the CheckBox is checked or unchecked.
Thanks very much.
I usually use the following style for displaying a ListBox using CheckBoxes (You can use RadioButtons too by just replacing the CheckBox control with a RadioButton
<Style x:Key="CheckBoxListBoxStyle" TargetType="{x:Type ListBox}">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="KeyboardNavigation.DirectionalNavigation" Value="Cycle" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="2, 2, 2, 0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Background="Transparent">
<CheckBox IsHitTestVisible="False" Focusable="false"
Content="{TemplateBinding ContentPresenter.Content}"
IsChecked="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
Then it is simply used by something like
<ListBox ItemsSource="{Binding Players}"
Style="{StaticResource CheckBoxListBoxStyle}"
SelectedItem="{Binding SelectedPlayer, Mode=TwoWay}">
If you have something that should behave like a RadioButton, why not use a RadioButton?
Try configuring your ListBox to Selection Mode Single. And rather than a separate label you could just bind Name to the Content property of the CheckBox. I like the way that spaces. And you may need to implement InotifyPropertyChanged on player.

How to conditionally format axis values in Silverlight Toolkit LineSeries

I am trying to conditionally format the numbers that appear in a NumericAxis axis for a LineSeries (from Silverlight 4 Toolkit). To be more specific, I want numbers that are >=10000 and <=0.0001 to display in scientific notation, but I can't seem to make this work.
I can override the NumericAxisLabel template like this:
<Style x:Key="NumericAxisLabelStyle" TargetType="chartingToolkit:NumericAxisLabel">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="StringFormat" Value="{}{0:0.0E+00}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="chartingToolkit:NumericAxisLabel">
<TextBlock Text="{TemplateBinding FormattedContent}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But this will apply the scientific notation format to ALL labels in the axis. What I want is for the string format expression to "kick in" only when the condition I mentioned above occurs.
I was able to accomplish this in the LineDataPoint tooltip template fairly easy by using a binding with a custom value converter, like this:
<ControlTemplate TargetType="chartingToolkit:LineDataPoint">
<Grid x:Name="Root" Opacity="0">
<ToolTipService.ToolTip>
<StackPanel Margin="2,2,2,2">
<StackPanel Orientation="Horizontal">
<TextBlock Text="X:" />
<ContentControl Content="{Binding objResultValueX, Converter={StaticResource ToCustomStringFormat}}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Y:" />
<ContentControl Content="{Binding dblResultValueY, Converter={StaticResource ToCustomStringFormat}}"/>
</StackPanel>
</StackPanel>
</ToolTipService.ToolTip>
...
</Grid>
</ControlTemplate>
If only I could specify a converter for the "FormattedContent" in the NumericAxisLabelStyle like I do for LineDataPoint template...surely there must be a way!
Any ideas?
Thanks in advance for the help!
Try setting the DataContext of the TextBlock to FormattedContent. Then apply the converter to the Text property as so:
<Style x:Key="NumericAxisLabelStyle" TargetType="chartingToolkit:NumericAxisLabel">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value >
<ControlTemplate TargetType="chartingToolkit:NumericAxisLabel">
<TextBlock DataContext="{TemplateBinding FormattedContent}" Text ="{Binding Converter={StaticResource ToCustomStringFormat}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It's also possible to override the PrepareAxisLabel() method from the Toolkit's DisplayAxis class.
The source code for the original method (found here) is:
protected virtual void PrepareAxisLabel(Control label, object dataContext)
{
label.DataContext = dataContext;
label.SetStyle(AxisLabelStyle);
}
So, you can override it with something like:
public class MyLinearAxis : LinearAxis
{
protected override void PrepareAxisLabel(Control label, object dataContext)
{
(label as AxisLabel).StringFormat = "{0:c}"; // currency format, for example
dataContext = 10.0; // your own custom numeric value
base.PrepareAxisLabel(label, dataContext);
}
}
In this way, you can get total control over the label as it's created.

Data bound radio button list in WPF

I have a list of options in a data object, and I want to make the equivalent of a radio button list to allow the user to select one and only one of them. Functionality similar to a databound combo box, but in radio button format.
Silly me, I thought this would be built in, but no. How do you do it?
Basically, after reviewing the google results, I started with the info from an MSDN discussion thread where Dr. WPF provided an answer, which talks about styling a ListBox to look right. However, when the listbox is disabled, the background was an annoying color that I couldn't get rid of for the life of me, until I read the MSDN example of the ListBox ControlTemplate, which shows the secret Border element that was kicking my background butt.
So, the final answer here was this style:
<Style x:Key="RadioButtonList" TargetType="{x:Type ListBox}">
<!-- ControlTemplate taken from MSDN http://msdn.microsoft.com/en-us/library/ms754242.aspx -->
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="95"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border Name="Border" Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
CornerRadius="2">
<ScrollViewer Margin="0" Focusable="false">
<StackPanel Margin="2" IsItemsHost="True" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background"
Value="Transparent" />
<Setter TargetName="Border" Property="BorderBrush"
Value="Transparent" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Name="theBorder" Background="Transparent">
<RadioButton Focusable="False" IsHitTestVisible="False"
IsChecked="{TemplateBinding IsSelected}">
<ContentPresenter />
</RadioButton>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
Which provides a ControlTemplate for, and styles, the ListBox and the Items. And it gets used like this:
<ListBox Grid.Column="1" Grid.Row="0" x:Name="TurnChargeBasedOnSelector" Background="Transparent"
IsEnabled="{Binding Path=IsEditing}"
Style="{StaticResource RadioButtonList}"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainForm}}, Path=DataContext.RampTurnsBasedOnList}"
DisplayMemberPath="Description" SelectedValuePath="RampTurnsBasedOnID"
SelectedValue="{Binding Path=RampTurnsBasedOnID, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}"/>
The more I spend time with WPF, the more I think it makes the trivial insanely difficult and the insanely difficult trivial. Enjoy. -Scott
Super Simple, MVVM friendly, leveraging DataTemplates for types.
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type local:Option}">
<RadioButton Focusable="False"
IsHitTestVisible="False"
Content="{Binding Display}"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}">
</RadioButton>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Options}" SelectedItem="{Binding SelectedOption}"/>
</Grid>
View Model, etc:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new Vm();
}
}
public class Vm
{
public Option[] Options { get { return new Option[] {
new Option() { Display = "A" },
new Option() { Display = "B" },
new Option() { Display = "C" } }; } }
public Option SelectedOption { get; set; }
}
public class Option
{
public string Display { get; set; }
}
If you wrap your option into a specific type (or likely it is already). You can just set a DataTemplate for that type, WPF will automatically use it. (Define DataTemplate in ListBox resources to limit the scope of where the DataTemplate will be applied).
Also use group name in the DataTemplate to set the group if you want.
This is much simpler than changing the control template, however it does mean that you get a blue line on selected items. (Again, nothing a bit of styling can't fix).
WPF is simple when you know how.
Bind the listbox to the ItemsSource of a ListBox with a list of objects that have a property Name (this can change)
<ListBox Name="RadioButtonList">
<ListBox.ItemTemplate >
<DataTemplate >
<RadioButton GroupName="radioList" Tag="{Binding}" Content="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
important GroupName="radioList"
I've done this through a ValueConverter that converts an enum to a bool. By passing the enum value that your radio button represents as the ConverterParameter, the converter returns whether this radio button should be checked or not.
<Window.Resources>
<Converters:EnumConverter x:Key="EnumConverter" />
</Window.Resources>
<RadioButton IsChecked="{Binding Path=MyEnum, Mode=TwoWay,
Converter={StaticResource EnumConverter},
ConverterParameter=Enum1}"}
Content="Enum 1" />
<RadioButton IsChecked="{Binding Path=MyEnum, Mode=TwoWay,
Converter={StaticResource EnumConverter},
ConverterParameter=Enum2}"}
Content="Enum 2" />
EnumConverter is defined as follows:
public class EnumConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType.IsAssignableFrom(typeof(Boolean)) && targetType.IsAssignableFrom(typeof(String)))
throw new ArgumentException("EnumConverter can only convert to boolean or string.");
if (targetType == typeof(String))
return value.ToString();
return String.Compare(value.ToString(), (String)parameter, StringComparison.InvariantCultureIgnoreCase) == 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType.IsAssignableFrom(typeof(Boolean)) && targetType.IsAssignableFrom(typeof(String)))
throw new ArgumentException("EnumConverter can only convert back value from a string or a boolean.");
if (!targetType.IsEnum)
throw new ArgumentException("EnumConverter can only convert value to an Enum Type.");
if (value.GetType() == typeof(String))
{
return Enum.Parse(targetType, (String)value, true);
}
//We have a boolean, as for binding to a checkbox. we use parameter
if ((Boolean)value)
return Enum.Parse(targetType, (String)parameter, true);
return null;
}
}
Note that I don't databind to the list of enums to generate the radio buttons, I've done them by hand. If you wanted to fill the list of radio buttons through a binding, I think you'll need to change the IsChecked binding to a MultiBinding which binds to both the current value and the radio's enum value, because you cannot use a binding on ConverterParameter.
Sorry, I'd like to put this response to Scott O's post as a comment on his post, but I do not yet have the reputation to do that. I really liked his answer as it was a style-only solution and hence didn't require any added code-behind or creating a custom-control, etc.
However, I did have one issue when I then went to try using controls inside the ListBoxItems. When I use this style I am unable to focus any of the contained controls due to this line:
<RadioButton Focusable="False"
IsHitTestVisible="False"
IsChecked="{TemplateBinding IsSelected}">
The radio button needs to turn off Focusable and IsHitTestVisible for the IsChecked binding to work correctly. To get around this, I changed the IsChecked from a TemplateBinding to a regular binding, which allowed me to make it a two-way binding. Removing the offending settings gave me this line:
<RadioButton IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected, Mode=TwoWay}">
Which now allows me to focus any controls contained in ListBoxItems as expected.
Hope this helps.
I took my inspiration from Jon Benson's blog entry, but modified his solution to use enumerations that have a description attribute. So the key parts of the solution became:
Enumerator with descriptions
public enum AgeRange {
[Description("0 - 18 years")]
Youth,
[Description("18 - 65 years")]
Adult,
[Description("65+ years")]
Senior,
}
Code for reading descriptions and returning key/value pairs for binding.
public static class EnumHelper
{
public static string ToDescriptionString(this Enum val)
{
var attribute =
(DescriptionAttribute)
val.GetType().GetField(val.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false).
SingleOrDefault();
return attribute == default(DescriptionAttribute) ? val.ToString() : attribute.Description;
}
public static List<KeyValuePair<string,string>> GetEnumValueDescriptionPairs(Type enumType)
{
return Enum.GetValues(enumType)
.Cast<Enum>()
.Select(e => new KeyValuePair<string, string>(e.ToString(), e.ToDescriptionString()))
.ToList();
}
}
Your Object Data Provider in XAML
<ObjectDataProvider
ObjectType="{x:Type local:EnumHelper}"
MethodName="GetEnumValueDescriptionPairs"
x:Key="AgeRanges">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:AgeRange" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
Your ListBox in XAML
<ListBox
ItemsSource="{Binding Source={StaticResource AgeRanges}}"
SelectedValue="{Binding SelectedAgeRange}"
SelectedValuePath="Key">
<ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}"
Content="{Binding Value}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The property (e.g. in your view model) that you are binding to
public class YourViewModel : INotifyPropertyChanged
{
private AgeRange _selectedAgeRange;
public AgeRange SelectedAgeRange
{
get { return _selectedAgeRange; }
set
{
if (value != _selectedAgeRange)
{
_selectedAgeRange = value;
OnPropertyChanged("SelectedAgeRange");
}
}
}
}
I cheated:
My solution was to bind the list box programaticly since that is all that seemed to work for me:
if (mUdData.Telephony.PhoneLst != null)
{
lbPhone.ItemsSource = mUdData.Telephony.PhoneLst;
lbPhone.SelectedValuePath = "ID";
lbPhone.SelectedValue = mUdData.Telephony.PrimaryFaxID;
}
The XAML looks like this:
<ListBox.ItemTemplate >
<DataTemplate >
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<RadioButton
IsChecked="{Binding Path=PrimaryPhoneID}"
GroupName="Phone"
x:Name="rbPhone"
Content="{Binding Path=PrimaryPhoneID}"
Checked="rbPhone_Checked"/>
<CheckBox Grid.Column="2" IsEnabled="False" IsChecked="{Binding Path=Active}" Content="{Binding Path=Number}" ></CheckBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
And in my event to read the value of the radio button as it is selected looks like this:
private void rbPhone_Checked(object sender, RoutedEventArgs e)
{
DataRowView dvFromControl = null;
dvFromControl = (DataRowView)((RadioButton)sender).DataContext;
BindData.Telephony.PrimaryPhoneID = (int)dvFromControl["ID"];
}
Hope that helps someone.

Resources