Can you create ItemTemplate for Stack Panels with bindings? - wpf

I have a stack panel of stack panels with similar controls. Could a template be used instead? Each field is a property of an Custom Object.
<StackPanel Margin="10,0,0,0">
<StackPanel x:Name="ReferenceStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Reference" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=UReference, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="TitleStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Title" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="SponsorStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Sponsor" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Sponsor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="AlignmentStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Alignment" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Alignment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="NTAStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="NTA" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=NTA, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="KeywordsStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Keywords" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Keywords, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="FocusAreasStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="FocusAreas" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=FocusAreas, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="PlatformStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Platform" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Platform, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="FiscalYearStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="FiscalYear" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=FiscalYear, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="OriginatingDocumentStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="OriginatingDocument" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=OriginatingDocument, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="RecommendationsStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Recommendations" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Recommendations, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
</StackPanel>
I was thinking something like this but it didn't work.
<DataTemplate x:Key="Template">
<StackPanel>
<Label Content="{Binding}" />
<TextBox Text="{Binding}"/>
</StackPanel>
</DataTemplate>
I am also reading something about ContentControl but not sure how they work. It is one object I am trying to display, in an edit properties view.

The simplest solution to this would be if it's ok to have your label and textbox side by side.
Then you could use a propertygrid:
https://github.com/xceedsoftware/wpftoolkit/wiki/PropertyGrid
The toolkit is not free for commercial use, however, the source is available and you could take that and customise/simplify it for your usage.
If that does not suit then you could use reflection to build out a collection of property viewmodels which have PropertyName and PropertyValue.
Add them to a List you bind to itemssource of an itemscontrol.
You can then template each to whatever you like.
I'm not clear what that Visibility binding is all about, can't work out what the intent is there.
You could, however, use an attribute to control which properties are displayed.
The following proof of concept iterates properties to build out a list. It is very quick and dirty and intended just to get you started rather than a cut and paste solution.
MainWindow
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<ItemsControl ItemsSource="{Binding PropertyValues}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}"/>
<TextBox Text="{Binding Value}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
MainWindowViewModels and some classes.
public partial class MainWindowViewModel : ObservableValidator
{
[ObservableProperty]
private List<PropertyNameValue> propertyValues = new();
private PropertyInfo[] propertyList = typeof(Thingummy).GetProperties();
private Thingummy thing = new Thingummy { Reference="AAAAA", Sponsor="BBBB", Title="CCCC"};
private void GetProperties()
{
foreach (PropertyInfo property in propertyList)
{
PropertyNameValue pnv = new PropertyNameValue{ Name= property.Name, Value=property.GetValue(thing).ToString() };
PropertyValues.Add(pnv);
}
}
private void SetProperties()
{
for (int i = 0; i < propertyList.Length; i++)
{
propertyList[i].SetValue(thing, PropertyValues[i].Value);
}
}
public MainWindowViewModel()
{
GetProperties();
}
}
public class Thingummy
{
public string Reference { get; set; }
public string Title { get; set; }
public string Sponsor { get; set; }
}
public class PropertyNameValue
{
public string Name { get; set; }
public string Value { get; set; }
}
I don't know what type your class is you're editing. I've called mine Thingummy and of course it only has the first few properties.
There's no save button but that'd call SetProperties.
You could potentially make this generic and pass in a type to a generic viewmodel if you put your mind to it.
Make the itemssource a list and define different viewmodels for string, double etc. Define a template for each type. Perhaps put any get/ set logic in there as well.
Anyhow, this spins up and I can edit ok.

Related

Data binding cardview control wpf

Here is my xaml
<syncfusion:CardView Grid.Column="1"
Grid.Row="2"
Grid.ColumnSpan="4"
Grid.RowSpan="4"
ItemsSource="{Binding Events}">
<syncfusion:CardView.DataContext>
<viewModel:DefaultViewModel />
</syncfusion:CardView.DataContext>
<syncfusion:CardView.ItemTemplate>
<DataTemplate>
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBoxItem>
<ListBoxItem.DataContext>
<viewModel:DefaultViewModel />
</ListBoxItem.DataContext>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Event Name:" />
<TextBlock Text="{Binding EventName}"
Margin="5,0,0,0" />
</StackPanel>
</ListBoxItem>
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Event Genre:" />
<TextBlock Text="{Binding EventGenre}"
Margin="5,0,0,0" />
</StackPanel>
</ListBoxItem>
</ListBox>
</DataTemplate>
</syncfusion:CardView.ItemTemplate>
<syncfusion:CardView.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding EventName}" />
</DataTemplate>
</syncfusion:CardView.HeaderTemplate>
</syncfusion:CardView>
My viewModel
public DefaultViewModel()
{
CustomerDatabaseEntities context = new CustomerDatabaseEntities();
Events = (from data in context.Event_Details select data.eventTitle).ToList();
}
public string EventName {get;set;}
public string EventGenre {get;set;}
My Model
public partial class Event_Details
{
public string eventTitle { get; set; }
public string eventGenre { get; set; }
}
I'm trying to display each value of eventTitle and eventGenre in its own card similar to this:
.
Each event will have its own card, with its respective details.Although the card view was able to show that i had two different events(refer to link above), both the eventTitle and eventGenre were blank. How would i be able to display each of these values in their own cards?
<DataTemplate>
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Event Name:" />
<TextBlock Text="{Binding eventTitle }"
Margin="5,0,0,0" />
</StackPanel>
</ListBoxItem>
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Event Genre:" />
<TextBlock Text="{Binding eventGenre }"
Margin="5,0,0,0" />
</StackPanel>
</ListBoxItem>
</ListBox>
</DataTemplate>

Binding List to a ListBox in WPF

I have a class called Person, with just name, age and gender properties. And I also have a List<Person> of 5 people (hard-coded for now, but not relevant). I want to bind it to a ListBox through XAML so it has three TextBlocks for each of the properties:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=name}" />
<TextBlock Text="{Binding Path=gender}" />
<TextBlock Text="{Binding Path=age}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
The problem is that I don't know what to use as a data context or item source or whatever.
Any ideas?
<ListBox ItemsSource="{Binding People}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=name}" />
<TextBlock Text="{Binding Path=gender}" />
<TextBlock Text="{Binding Path=age}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
and in your code behind (ViewModel):
public ObservableCollection<Person> people = new ObservableCollection<Person>();
public ObservableCollection<Person> People { get { return people; } }
You can omit Path= in your bindings because it is the default property

WPF different dataContext for comboBox ItemsSource

I have a ItemControl and inside I have a comboBox, what I'm trying to achieve is to have a different dataContext for the comboBox itemsSource
This is my itemControl:
<ItemsControl ItemsSource="{Binding Types}" Margin="0,25,0,0" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel Margin="8">
<Border CornerRadius="6" BorderBrush="Gray" Background="LightGray" BorderThickness="2" DockPanel.Dock="Top">
<StackPanel >
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Name:" FontSize="15" FontWeight="SemiBold"/>
<TextBox Text="{Binding Name}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Type:" FontSize="15" FontWeight="SemiBold"/>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.EmployeeStatus}"
SelectedValue="{Binding Type}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Units:" FontSize="15" FontWeight="SemiBold"/>
<TextBox Text="{Binding Units}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Range:" FontSize="15" FontWeight="SemiBold"/>
<TextBox Text="{Binding Range}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Scale:" FontSize="15" FontWeight="SemiBold"/>
<TextBox Text="{Binding Scale}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Reason:" FontSize="15" FontWeight="SemiBold"/>
<TextBox Text="{Binding Reason}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Description:" FontSize="15" FontWeight="SemiBold" />
<TextBox Text="{Binding Description}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
</StackPanel>
</Border>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I saw something similar but couldn't make the connection to my problem
WPF ComboBox bind itemssource to different datacontext in MVVM
Solution 1: Each ComboBox has different items
You must create appropriate type with ComboBox items source.
Example:
public class MyType
{
public string Name { get; set; }
public List<string> Types { get; set; }
public string Type { get; set; }
//...
}
Now you can binding ComboBox items source to different source:
<ItemsControl ItemsSource="{Binding Types}" Margin="0,25,0,0" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel Margin="8">
<Border CornerRadius="6" BorderBrush="Gray" Background="LightGray" BorderThickness="2" DockPanel.Dock="Top">
<StackPanel >
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Name:" FontSize="15" FontWeight="SemiBold"/>
<TextBox Text="{Binding Name}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Type:" FontSize="15" FontWeight="SemiBold"/>
<ComboBox ItemsSource="{Binding Path=Types}"
SelectedValue="{Binding Type}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
...
</ItemsControl>
Here you can find example solution.
Solution 2: All ComboBox have the same items
public class MyType
{
public string Name { get; set; }
public string Type { get; set; }
}
class MyViewModel
{
private List<MyType> _types;
public List<MyType> Types
{
get { return _types; }
set { _types = value; }
}
public List<string> TypesItemsSource { get; set; }
}
XAML code:
<ItemsControl ItemsSource="{Binding Types}" Margin="0,25,0,0" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel Margin="8">
<Border CornerRadius="6" BorderBrush="Gray" Background="LightGray" BorderThickness="2" DockPanel.Dock="Top">
<StackPanel >
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Name:" FontSize="15" FontWeight="SemiBold"/>
<TextBox Text="{Binding Name}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Text="Type:" FontSize="15" FontWeight="SemiBold"/>
<ComboBox ItemsSource="{Binding Path=DataContext.TypesItemsSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
SelectedValue="{Binding Type}" Width="70" Margin="10,0,0,0"/>
</StackPanel>
...
</ItemsControl>
Here you can find example solution.
i use "marker interfaces" to find the right datacontext
public interface IDataContextMarker{} //just an empty interface
so within the view where your viewmodel is bound to implement this interface
public class MyView : IDataContextMarker {}
and now you can use the interface with relativesource binding instead of controls or ancestorlevel, that makes thing easier for some cases :)
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:IDataContextMarker}}, Path=DataContext.EmployeeStatus}"

Control size of ListBoxItem (with DataTemplate) using RadioButtons

I´m displaying images in a ListBox and i want to control the size (small, medium, big) of the images with RadionButtons. The ItemsSource of the ListBox is bound to a property of a viewmodel. My current solution is to use an Image for each size and bind the Visibility of each Image to the IsChecked property to the corresponding RadioButton. But i wonder if there is a better solution to get it work, especially using bindings and not duplicating items for various sizes. Using animations for the size changes would also be great.
Here´s what i have so far.
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding Images}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Image x:Name="smallImage" Width="80" Height="45" Source="{Binding}" Visibility="{Binding IsChecked, ElementName=SmallSizeChecked, Converter={StaticResource boolToVisibility}}" />
<Image x:Name="mediumImage" Width="160" Height="90" Source="{Binding}" Visibility="{Binding IsChecked, ElementName=MediumSizeChecked, Converter={StaticResource boolToVisibility}}"/>
<Image x:Name="bigImage" Width="320" Height="180" Source="{Binding}" Visibility="{Binding IsChecked, ElementName=BigSizeChecked, Converter={StaticResource boolToVisibility}}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<RadioButton Content="small" Margin="0,0,10,0" GroupName="ItemSize" x:Name="SmallSizeChecked" />
<RadioButton Content="medium" Margin="0,0,10,0" GroupName="ItemSize" x:Name="MediumSizeChecked" IsChecked="True" />
<RadioButton Content="big" GroupName="ItemSize" x:Name="BigSizeChecked"/>
</StackPanel>
</Grid>
This can be easily achieved by using IValueConverters with parameters.
here is more elegant way then converters. i have not compiled it but will work after some fixes.
C#:
public class VM
{
public List<string> Images { get; set; }
public bool SmallSizeChecked { get; set; }
public bool MediumSizeChecked { get; set; }
public bool BigSizeChecked { get; set; }
public int size
{
get
{
if(SmallSizeChecked) return 100;
if(MediumSizeChecked) return 200;
if(BigSizeChecked) return 300;
return 100;
}
}
}
XAML:
<local:VM x:Key="mv" />
<RadioButton x:name="SmallSizeChecked" ischecked="{Binding mv.SmallSizeChecked, Mode=Twoway}"/>
<RadioButton x:name="MediumSizeChecked" ischecked="{Binding mv.MediumSizeChecked, Mode=Twoway/>
<RadioButton x:name="BigSizeChecked" ischecked="{Binding mv.BigSizeChecked, Mode=Twoway}"/>
<ListBox ItemsSource="{Binding mv.Images}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Image x:Name="img" Source="{Binding}" Width="80" Height="{Binding Path=size,Source={staticResource mv}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm sure you will get the idea and will extend it for Width property too.
Dipak.

Silverlight: DataGrid inside ListBox. Binding on DataGrid Column to a parent listbox's ItemsSource property. Silverlight

I'm a little puzzled with this one. I have a Collection called "AllProducts", which has a collection inside called "ProductGroups" (to group items separately) which inside contain a collection of "Product" objects called "LineItems" (the actual items).
To set this up, I have set a ListBox with a DataGrid inside the itemtemplate for the ListBox's Items. Setting the ItemsSource of the listbox to "ProductGroups" and the DataGrid(In the itemtemplate) has an ItemsSource pointing to LineItems.
The DataGrid contains Columns:
"Select" -- A checkbox and a radiobutton
"Image" -- string
"Name" -- string
"Description" -- string
"Price" -- string
The "ProductGroup" collection has a bool property called "IsListItem" per group, which is supposed to tell me if you can select multiple or a single item for that group (hence the checkbox and radiobutton in the first column of the DataGrid). I want the checkbuttons and radiobuttons visibility property to be bound to "IsListItem" bool which I have already set up with a BoolToVisibility converter with an "IsInverted" property to switch them back and forth.
The problem that I'm running into is that I want the first column of the DataGrid which contains the checkboxes/radiobuttons to be bound to the IsLineItem of ProductGroups (which is the ListBox's ItemsSource. But Since the DataGrid's ItemsSource is bound to LineItems, the DataContext of the DataGrid is set to LineItems and I can't access anything outside of it.
Here's some code to help:
ListBox XAML:
<sdk:TabItem Header="Pmt" x:Name="Payment">
<Canvas x:Name="PaymentRoot" DataContext="{Binding Products.ProductGroups}">
<Rectangle Height="418" Canvas.Top="-14" Width="560" Style="{StaticResource MappingRectangleBG}" />
<StackPanel Canvas.Left="20" Canvas.Top="20" Width="520" Height="360">
<ListBox x:Name="lstProductGroups" ItemsSource="{Binding}" ItemTemplate="{StaticResource ProductListItem}" />
</StackPanel>
</Canvas>
</sdk:TabItem>
ListBox ItemTemplate XAML:
<sdk:DataGrid x:Name="dgLineItems" ItemsSource="{Binding LineItems}">
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn Header="Select">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Visibility="{Binding IsListType, Converter={StaticResource boolToVisibilityConverter}}" />
<RadioButton Visibility="{Binding IsListType, Converter={StaticResource inverseBoolToVisibilityConverter}}" GroupName="{Binding GroupName}"/>
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn Header="Image">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding ImageUrl}" Height="50" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTextColumn Header="Item Name"
Binding="{Binding Name}" />
<sdk:DataGridTextColumn Header="Item Price"
Binding="{Binding Price}" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</StackPanel>
</DataTemplate>
And my Objects:
public class AllProducts
{
public IEnumerable<ProductOptionGroup> ProductGroups;
}
public class ProductOptionGroup
{
public string GroupName;
public IEnumerable<Product> LineItems;
public bool IsListType;
}
public class Product
{
public int ID;
public int OrdinalNumber;
public string Name;
public string Description;
public Decimal Price;
public string ImageUrl;
public CartItemType Type;
}
(MichaelS): I tried setting it to the Parent "PaymentRoot" Canvas' DataContext but it isn't doing anything for me. Here is what I tried:
<CheckBox Visibility="{Binding ElementName=PaymentRoot, Path=DataContext.IsListType, Converter={StaticResource boolToVisibilityConverter}}" />
<RadioButton Visibility="{Binding ElementName=PaymentRoot, Path=DataContext.IsListType, Converter={StaticResource inverseBoolToVisibilityConverter}}" GroupName="{Binding ElementName=PaymentRoot, Path=DataContext.GroupName}"/>
(MichaelS): here's how it's set up in my VM:
private AllProducts products;
public AllProducts Products
{
get
{
return products;
}
set
{
//Products.ProductGroups[0].LineItems[0].
products = value;
RaisePropertyChanged("Products");
}
}
Update:
The below code won't work since it's a known issue that was discovered late in the Silverlight 3 timeframe.
Setting the Binding in the LoadingRow event using column.GetCellContent(e.Row) should solve the issue.
In this particular case , you want be able to do that since the dataGrid itself is a dataTemplate of another control.
Try this:
Wrap your datagrid with another Grid. Name it, and use it for the element binding.
This code should work:
<StackPanel>
<Grid x:Name="GridDataHolder">
<sdk:DataGrid x:Name="dgLineItems" ItemsSource="{Binding LineItems}">
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn Header="Select">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Visibility="{Binding ElementName=GridDataHolder, Path=DataContext.IsListType, Converter={StaticResource boolToVisibilityConverter}}" />
<RadioButton Visibility="{Binding ElementName=GridDataHolder, Path=DataContext.IsListType, Converter={StaticResource inverseBoolToVisibilityConverter}}" GroupName="{Binding ElementName=GridDataHolder, Path=DataContext.GroupName}"/>
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn Header="Image">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding ImageUrl}" Height="50" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTextColumn Header="Item Name"
Binding="{Binding Name}" />
<sdk:DataGridTextColumn Header="Item Price"
Binding="{Binding Price}" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
</StackPanel>
By the way, i'm not sure if binding works with public members, you may need to change those binded members to public properties.
Finally got it fixed! What I had to end up doing was getting rid of the DataGrid altogether because a lot of controls from the toolkit seem to have that bug not being able to bind outside even through Element Binding.
I turned the DataGrid into a ListBox with another DataTemplate for the LineItems completely customizing the look of it to achieve a similar look that I had with the DataGrid.
Also to note: I tried at first binding to the StackPanel outside of the DataTemplate through Element Binding but it seemed to have a problem with that. So I set the grid inside the DataTemplate's DataContext and then I made the checkbox and radiobutton bound to the grid inside the Parent Listbox's dataTemplate through element binding and that did the trick!
Here is some working code for anybody who runs into this same issue later on!:
<DataTemplate x:Key="LineItemsTemplate">
<StackPanel Orientation="Horizontal">
<StackPanel Height="100" Width="100">
<StackPanel Height="40" Orientation="Vertical">
<RadioButton Content="{Binding Name}" Visibility="{Binding ElementName=GridDataHolder, Path=DataContext.IsListType, Converter={StaticResource boolToVisibilityConverter}}" GroupName="{Binding ElementName=GridDataHolder, Path=DataContext.GroupName}"/>
<CheckBox Content="{Binding Name}" Visibility="{Binding ElementName=GridDataHolder, Path=DataContext.IsListType, Converter={StaticResource inverseBoolToVisibilityConverter}}"/>
</StackPanel>
<Image Source="{Binding ImageUrl}" Height="50" />
</StackPanel>
<TextBlock TextWrapping="Wrap" Text="{Binding Description}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="ProductListItem">
<StackPanel x:Name="GridDataHolder">
<TextBlock TextWrapping="Wrap" Text="{Binding GroupName}" VerticalAlignment="Top" d:LayoutOverrides="Width"/>
<ListBox x:Name="lstProductGroups" ItemsSource="{Binding LineItems}" ItemTemplate="{StaticResource LineItemsTemplate}">
</ListBox>
</StackPanel>
</DataTemplate>
<sdk:TabItem Header="Pmt" x:Name="Payment">
<Canvas>
<Rectangle Height="418" Canvas.Top="-14" Width="560" Style="{StaticResource MappingRectangleBG}" />
<ScrollViewer Height="389" Width="545" x:Name="PaymentRoot" DataContext="{Binding Products.ProductGroups}">
<StackPanel Orientation="Vertical" ScrollViewer.VerticalScrollBarVisibility="Auto" Width="500" HorizontalAlignment="Center">
<ListBox x:Name="lstProductGroups" ItemsSource="{Binding}" ItemTemplate="{StaticResource ProductListItem}" />
</StackPanel>
</ScrollViewer>
</Canvas>
</sdk:TabItem>
Thanks MichaelS for all your help! You got me going the right way!

Resources