SL4: DataGrid and contextmenu
There is a nice implementation of contextmenu by Jesse Bishop in SL4. It supports commands as well as click handlers
we could use that control and add context sensitive contextmenu to datagrid
I created a basic application, Here is the xaml for the mainpage. we have a datagrid which is bound to a list of persons
<UserControl xmlns:my=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data” x:Class=”SilverlightApplication1.MainPage”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation“
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml“
xmlns:d=”http://schemas.microsoft.com/expression/blend/2008“
xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006“
xmlns:menu=”clr-namespace:ContextMenuControls;assembly=ContextMenuControls”
mc:Ignorable=”d”
d:DesignHeight=”300″ d:DesignWidth=”400″>
<Grid x:Name=”LayoutRoot” Background=”White”>
<my:DataGrid x:Name=”datagrid1″ ItemsSource=”{Binding Persons}”></my:DataGrid>
</Grid>
</UserControl>
when the rightmouse button is down on the grid. we do a hit test to get the row( the person item that was clicked), create a menuitem with person’s name and add to the Items of the contextmenu
when the item is clicked we remove the person from the list
void datagrid1_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
IEnumerable elements = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(LayoutRoot), datagrid1);
DataGridRow row = null;
foreach (UIElement ele in elements)
{
if (ele is DataGridRow)
{
row = ele as DataGridRow;
break;
}
}
ContextMenu cm = new ContextMenu();
Person p = row.DataContext as Person;
MenuItem mi = new MenuItem { Text = “Delete ” + p.FirstName, Tag=p };
mi.Click += new MenuItem.ClickHandler(mi_Click);
cm.Items.Add(mi);
datagrid1.SetValue(ContextMenu.ContextMenuProperty, cm);
cm.IsOpen = true;
}
void mi_Click(object sender, EventArgs e)
{
Persons.Remove((sender as MenuItem).Tag as Person);
}
you can download the sample here
Same XAML Silverlight and WPF – different result
I did not know the following would produce different results in WPF and Silverlight
<Grid>
<TextBlock Text=”{Binding RelativeSource={RelativeSource Self}, Path=Tag}” Tag=”hello”/>
</Grid>
In WPF, you see “Hello”. In silverlight you dont see anything
The following XAML produces same result in WPF and Silverlight
<Grid>
<TextBlock Tag=”hello” Text=”{Binding RelativeSource={RelativeSource Self}, Path=Tag}” />
</Grid>
ListBox and scrolling
When the listbox is bound to some data and when the data changes we may want to make the first item in the list visible. That is not the default behaviour and ScrollIntoView(Item[0]) wont work. here is a way to reset the scrollposition
In the sample, I had the listbox’s are bound to 200 items and when the button is clicked I set the items to 20. the listbox on the left shows the default behaviour , the listbox on the right has the ScrollViewer position changed to show the first item 
update: Looks like this method still has issues when the number of items changes from a very low number to high number where the scrollbar appears and disappears as pointed out in this post. May be a bug?
update 2: Mog Liang (Microsoft Online Community Support) says “This is an known issue caused by ListBox virtualization. Currently, an workaround is replace VirtualizingStackPanel with StackPanel, however, this will drop the listbox performance.”
Here is the XAML and codebehind used in the sample
<Grid x:Name=”LayoutRoot” Margin=”5″>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Content=”set to 20 items” Height=”28″ Width=”100″ HorizontalAlignment=”Right” Click=”Button_Click”/>
<ListBox Grid.Column=”1″ Height=”200″ x:Name=”list1″ ItemsSource=”{Binding MyList}”/>
<ListBox Grid.Column=”2″ Height=”200″ x:Name=”list2″ ItemsSource=”{Binding MyList}”/>
</Grid>
public partial class MainPage : UserControl, INotifyPropertyChanged
{
public IEnumerable<string> MyList { get; set; }
public MainPage()
{
InitializeComponent();
MyList = Enumerable.Range(0, 200).Select(i => “Item..” + i.ToString()).ToList();
this.DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MyList = Enumerable.Range(0, 20).Select(i => “Item..” + i.ToString()).ToList();
NotifyPropertyChanged(“MyList”);
ScrollViewer sv = GetChild<ScrollViewer>(list2);
sv.ScrollToVerticalOffset(0);
}
public static T GetChild<T>(DependencyObject obj) where T : DependencyObject
{
DependencyObject child = null; for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child.GetType() == typeof(T))
{
break;
}
else if (child != null)
{
child = GetChild<T>(child);
if (child != null && child.GetType() == typeof(T))
{
break;
}
}
}
return child as T;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
Telerik Silverlight RadGridView Issues
I am new to Silverlight RadGridView control from (Q2 2009). I was trying to use a nested RadGridView in the RowDetailsTemplate like below.
Update: With the help of Vlad from Telerik, learned that there is a Service pack released which fixed issues 2 and 3, but scrolling seems to be still slow when compared to the regular DataGrid doing the samething and you see lot of flickering
I am having multiple issues.
<grid:RadGridView x:Name=”RadGridView1″ ShowGroupPanel=”False” IsReadOnly=”True”
RowIndicatorVisibility=”Collapsed”
AutoGenerateColumns=”False” ColumnsWidthMode=”Fill”
RowDetailsVisibilityMode=”Visible”
CanUserFreezeColumns=”False” >
<grid:RadGridView.Columns>
…
</grid:RadGridView.Columns>
<grid:RadGridView.RowDetailsTemplate>
<DataTemplate>
<Grid>
<grid:RadGridView ShowColumnHeaders=”False” ShowGroupPanel=”False”
ItemsSource=”{Binding ChildItems}” IsReadOnly=”True”
Visibility=”Visible”
AutoGenerateColumns=”False” ColumnsWidthMode=”Fill”
RowDetailsVisibilityMode=”Collapsed”
CanUserFreezeColumns=”False” >
<grid:RadGridView.Columns>
…
</grid:RadGridView.Columns>
</grid:RadGridView>
</Grid>
</DataTemplate>
</grid:RadGridView.RowDetailsTemplate>
</grid:RadGridView>
1. With 10 rows of data. It is just not usable as scrolling takes long time. that is just for starters
2. I dont want to display any RowIndicator for the inner RadGridView. The property “RowIndicatorVisibility” works correctly when set to “Collapsed” on the outer RadGridView when you add this property to the Inner RadGridView. you dont see any data in the Inner RadGridView
3. When the filter is applied, the inner RadGridView will not display any data
Tried to flatten the hierarchy but the filter functionality would be lost as I dont want to filter on the values of the InnerCollection and I could not find a way to tell dont include some values in the filter popup
If any one has any Ideas or workaround, please let me know
BTW, the same scenario when using the DataGrid that comes with Silverlight, it seemed to work just fine, except for the ability to filter (out of the box)
Silverlight forums error
The new forums seems to be faster and better organized. Now if only we can sign in to the forums can work without throwing errors with all the path and details. Could not get signed into forums all day today

Extended AutoCompleteBox sample updated to Silverlight 3
A while back I had a sample that extends AutoCompleteBox which worked in Silverlight 2. Here is the sample upgraded to Silverlight 3. I did not add/remove anything functional. just fixed the errors that are caused by the changes in base class(AutoCompleteBox)
DataBinding in Nested Controls
Databinding can get tricky in a hurry depending on the layout we have and the model we are binding to. Dan Wahlin suggests a way in this post
Here is another way without any code or additional classes.
DataContext is setup to be a instance of data, which has list of customers(having name and city as properties) and an array of strings for cities. we would like to display customers in datagrid and display list of Cities in ComboBox and select the appropriate city for the customer
namespace SilverlightApplication2
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.DataContext = new Data();
}
}
public class Data
{
public List<Customer> Customers { get; set; }
public string[] Cities { get; set; }
public Data()
{
Customers = new List<Customer>();
for (int i = 0; i < 10; i++)
Customers.Add(new Customer { Name=”Customer..” + i.ToString(), City=”City..”+i.ToString() });
Cities = new string[10];
for (int i = 0; i < 10; i++)
Cities[i] = “City..” + i.ToString();
}
}
public class Customer
{
public string Name { get; set; }
public string City { get; set; }
}
}
the UI is set up like this. just a DataGrid with DataGridTextColumn for Name of the customer and ComboxBox for cities in a DataGridTemplateColumn
Added a ContentControl( could be any control) to Resources which will have the same datacontext as the Root (Page/UserControl)
The ComboBox’s ItemsSource is set as shows in Bold, setting the source to the Resource and the path to its DataContext (in this case it will point to object of type “Data”) which has a property Cities. SelectedItem of the ComboBox is set to City of the customer
<UserControl xmlns:data=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data” x:Class=”SilverlightApplication2.MainPage”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation“
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml“
xmlns:d=”http://schemas.microsoft.com/expression/blend/2008“
xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006“
mc:Ignorable=”d” d:DesignWidth=”640″ d:DesignHeight=”480″>
<UserControl.Resources>
<ContentControl x:Key=”cc1″ ></ContentControl>
</UserControl.Resources>
<Grid x:Name=”LayoutRoot”>
<data:DataGrid AutoGenerateColumns=”False”
ItemsSource=”{Binding Path=Customers}” Name=”datagrid1″>
<data:DataGrid.Columns>
<data:DataGridTextColumn Width=”150″ Header=”Name” Binding=”{Binding Name}”/>
<data:DataGridTemplateColumn Width=”150″ Header=”City”>
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedItem=”{Binding City}”
ItemsSource=”{Binding Source={StaticResource cc1}, Path=DataContext.Cities}” ></ComboBox>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
</Grid>
</UserControl>
Here is what it looks like.

Alignment of label in Dataform
One of the forum users was looking to align the label in the Datafield of DataForm with the following code
<dataFormToolkit:DataField>
<dataFormToolkit:DataField.Label>
<TextBlock Text=”Categories” VerticalAlignment=”Top” />
</dataFormToolkit:DataField.Label>
<Grid>
<StackPanel x:Name=”listCategories” />
</Grid>
</dataFormToolkit:DataField>
sure enough, it doesnt work. I am not sure if there is easier way, but styling the Label does work, changes made to the default style in bold

<Style x:Key=”LabelStyle1″ TargetType=”dataInput:Label”>
<Setter Property=”IsTabStop” Value=”False”/>
<Setter Property=”Template”>
<Setter.Value>
<ControlTemplate TargetType=”dataInput:Label”>
<StackPanel Orientation=”Horizontal”>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name=”CommonStates”>
<VisualState x:Name=”Normal”/>
<VisualState x:Name=”Disabled”/>
</VisualStateGroup>
<VisualStateGroup x:Name=”ValidationStates”>
<VisualState x:Name=”Valid”/>
<VisualState x:Name=”Invalid”/>
</VisualStateGroup>
<VisualStateGroup x:Name=”RequiredStates”>
<VisualState x:Name=”NotRequired”/>
<VisualState x:Name=”Required”>
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration=”0″ Storyboard.TargetName=”ContentControl” Storyboard.TargetProperty=”FontWeight”>
<DiscreteObjectKeyFrame KeyTime=”0″ Value=”SemiBold”/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border Background=”{TemplateBinding Background}” BorderBrush=”{TemplateBinding BorderBrush}”
BorderThickness=”{TemplateBinding BorderThickness}” CornerRadius=”2″ Padding=”{TemplateBinding Padding}” VerticalAlignment=”Top”>
<ContentControl x:Name=”ContentControl” FontFamily=”{TemplateBinding FontFamily}”
FontSize=”{TemplateBinding FontSize}” FontStretch=”{TemplateBinding FontStretch}” FontWeight=”{TemplateBinding FontWeight}”
HorizontalContentAlignment=”{TemplateBinding HorizontalContentAlignment}”
IsTabStop=”False” VerticalContentAlignment=”{TemplateBinding VerticalContentAlignment}”
Cursor=”{TemplateBinding Cursor}” HorizontalAlignment=”{TemplateBinding HorizontalAlignment}”
VerticalAlignment=”{TemplateBinding VerticalAlignment}” Content=”{TemplateBinding Content}”
ContentTemplate=”{TemplateBinding ContentTemplate}” Foreground=”{TemplateBinding Foreground}”/>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<dataFormToolkit:DataField LabelStyle=”{StaticResource LabelStyle1}” >
<dataFormToolkit:DataField.Label>
<TextBlock Text=”Categories” />
</dataFormToolkit:DataField.Label>
<Grid>
<StackPanel x:Name=”listCategories”>
<CheckBox Content=”Checkbox1″/>
<CheckBox Content=”Checkbox2″/>
<CheckBox Content=”Checkbox3″/>
<CheckBox Content=”Checkbox4″/>
<CheckBox Content=”Checkbox5″/>
</StackPanel>
</Grid>
</dataFormToolkit:DataField>
![sample[1]](http://leeontech.files.wordpress.com/2009/11/sample1.png?w=301&h=150)