DataGrid Column Header text change from ViewModel
-
Monday, September 13, 2010 4:15 PM
Hi,
I need to change the column header text of the datagrid. I have defined a viewmodel and exposed a property, but I am not sure how I can bind the column header to this property.
I am trying to follow MVVM patern and using prism. I am very new to this and I am almost getting lost.
How can I resolve this problem
I am using Silverlight4 and VS2010
Thanks
ab
All Replies
-
Monday, September 13, 2010 4:57 PM
I am not sure if you can, the last I looked at binding Headers was in SL 3 but back then it was not a FrameworkElement so you could not bind to it. Not sure if it changed since then.
Can you post your xaml for the grid and your viewmodel bind property?
-
Monday, September 13, 2010 5:26 PM
What I am trying to do is very similar to an Email Client. When you click on th Inbox folder I need to show the Header for the recipient as "From" when in Send folder change the Header for the recipient as "To" If I can change this, I can use the same view for all the folders clicked, thats the plan. xaml
<UserControl.Resources> <DataTemplate x:Key="CheckboxGrid"> <Grid> <CheckBox IsThreeState="False" IsChecked="False"/> </Grid> </DataTemplate> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="Aqua" HorizontalAlignment="Stretch" Margin="2,0" > <sdk:DataGrid ItemsSource="{Binding GetMessages}" AutoGenerateColumns="False" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"> <sdk:DataGrid.Columns > <sdk:DataGridTemplateColumn CellTemplate="{StaticResource CheckboxGrid}" Width="SizeToCells"/> <sdk:DataGridTextColumn x:Name="ColParicipant" Binding="{Binding ParticipantName}" Header="From" IsReadOnly="True" Width="1*"/> <sdk:DataGridTextColumn x:Name="ColFacility" Binding="{Binding FacilityName}" Header="Facility" IsReadOnly="True" Width="1*"/> <sdk:DataGridTextColumn x:Name="ColPatient" Binding="{Binding PatientName}" Header="Patient Name" IsReadOnly="True" Width="1*"/> <sdk:DataGridTextColumn x:Name="ColSubject" Binding="{Binding Subject}" Header="Subject" IsReadOnly="True" Width="1*"/> <sdk:DataGridTextColumn x:Name="ColTime" Binding="{Binding Timestamp}" Header="Timestamp" IsReadOnly="True" Width="*"/> </sdk:DataGrid.Columns> </sdk:DataGrid> </Grid>public partial class MessageListView : UserControl { public MessageListView(MessageListVM viewModel) { InitializeComponent(); this.Loaded += (s, e) => { this.DataContext = viewModel; }; } }
(ViewModel)
public class MessageListVM { public MessageListVM(IMessageService messageService) { this.messageService = messageService; } public IEnumerable<Message> GetMessages { get { return messageService.GetFolderMessages(); } } public object GetHeader { get { return "From"; } } private readonly IMessageService messageService; }
-
Monday, September 13, 2010 5:40 PM
Have a look at this post, as you will see it is still not small task to achieve this.
-
Tuesday, September 14, 2010 12:42 PM
thanks....
I could get this working by creating the ViewModel as a local resource, and by providing a empty constructor for the viewmodel.
But I also set the datacontext to the same viewmdoel during load event of the view.
Is it right to do this? Will it create 2 instance of the same viewmodel ? I can post the code for this if required.
-
Tuesday, September 14, 2010 2:00 PM
A StaticResource declared ViewModel will create a new instance unless you use a ViewModel locator pattern. If you go this route maybe use your StaticResource ViewModel across your view and rather not set the DataContext on the load event.
http://johnpapa.net/silverlight/simple-viewmodel-locator-for-mvvm-the-patients-have-left-the-asylum/
-
Monday, September 20, 2010 8:15 PM
Thanks
I found another article ...
its not neat .. but will work for me...
-
Monday, September 20, 2010 10:01 PM
Would you mind posting the link of that article here to share with other communites.
-
Tuesday, September 21, 2010 8:44 AM
I dont remember the link to the article.In case I get I can post it.Right now I am pasting the code I have<UserControlx:Class="ccc.RI.SMViewDefault.View.DefaultListView"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:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"xmlns:conv="clr-namespace:ccc.RI.Common.Converters;assembly=ccc.RI.Common"mc:Ignorable="d"d:DesignHeight="300" d:DesignWidth="400"><UserControl.Resources><conv:BooleanFontConverter x:Key="boofont"></conv:BooleanFontConverter><conv:BindingConverter x:Key="BindCon"/><Style x:Key="ColBinding" TargetType="sdk:DataGridColumnHeader" ><Setter Property="ContentTemplate" ><Setter.Value><DataTemplate><ContentPresenter Content="{Binding Converter={StaticResource BindCon}}" /></DataTemplate></Setter.Value></Setter></Style><DataTemplate x:Key="ParticipantCol"><Grid><TextBlock Text="{Binding ParticipantName}" FontWeight="{Binding IsRead,Converter={StaticResource boofont}}" Margin="0,4"></TextBlock></Grid></DataTemplate></UserControl.Resources><Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" Margin="1,0,1,11"><TextBox Text="{Binding GetParticipantHeader}" x:Name="participantHeader" /><Border BorderBrush="#FFA6B6D6" BorderThickness="2" CornerRadius="2"x:Name="defaultview"><sdk:DataGrid ItemsSource="{Binding Path=GetMessages}"AutoGenerateColumns="False"ColumnHeaderStyle="{StaticResource ColBinding}"><sdk:DataGrid.Columns ><sdk:DataGridTemplateColumnCellTemplate="{StaticResource ParticipantCol}"Header="{Binding Text, ElementName=participantHeader}"Width="1*"SortMemberPath="ParticipantName"/></sdk:DataGrid.Columns></sdk:DataGrid></Border></Grid></UserControl>Also u need a converter.namespace ccc.RI.Common.Converters{public class BindingConverter : IValueConverter{public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){if (value.GetType().Name == "Binding"){ContentControl cc = new ContentControl();Binding newValue = value as Binding;newValue.Mode = BindingMode.TwoWay;cc.SetBinding(ContentControl.ContentProperty, newValue as Binding);return cc;}else{return value;}}public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){return null;}}}Hope this helpsI dont remember the link to the article.
In case I get I can post it.
Right now I am pasting the code I have
<UserControl
x:Class="ccc.RI.SMViewDefault.View.DefaultListView"
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:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:conv="clr-namespace:ccc.RI.Common.Converters;assembly=ccc.RI.Common"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<conv:BooleanFontConverter x:Key="boofont"></conv:BooleanFontConverter>
<conv:BindingConverter x:Key="BindCon"/>
<Style x:Key="ColBinding" TargetType="sdk:DataGridColumnHeader" >
<Setter Property="ContentTemplate" >
<Setter.Value>
<DataTemplate>
<ContentPresenter Content="{Binding Converter={StaticResource BindCon}}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="ParticipantCol">
<Grid>
<TextBlock Text="{Binding ParticipantName}" FontWeight="{Binding IsRead,Converter={StaticResource boofont}}" Margin="0,4"
></TextBlock>
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" Margin="1,0,1,11">
<TextBox Text="{Binding GetParticipantHeader}" x:Name="participantHeader" />
<Border BorderBrush="#FFA6B6D6" BorderThickness="2" CornerRadius="2"
x:Name="defaultview">
<sdk:DataGrid ItemsSource="{Binding Path=GetMessages}"
AutoGenerateColumns="False"
ColumnHeaderStyle="{StaticResource ColBinding}"
>
<sdk:DataGrid.Columns >
<sdk:DataGridTemplateColumn
CellTemplate="{StaticResource ParticipantCol}"
Header="{Binding Text, ElementName=participantHeader}"
Width="1*"
SortMemberPath="ParticipantName"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Border>
</Grid>
</UserControl>
Also u need a converter.
namespace ccc.RI.Common.Converters
{
public class BindingConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value.GetType().Name == "Binding")
{
ContentControl cc = new ContentControl();
Binding newValue = value as Binding;
newValue.Mode = BindingMode.TwoWay;
cc.SetBinding(ContentControl.ContentProperty, newValue as Binding);
return cc;
}
else
{
return value;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
}
Hope this helps

