Tag Archives: WPF

Dynamic ItemsSource in WPF

I was just playing around and I had an idea of binding data dyanmically to a telerik gridview. I have some 25 tables in a database and I give the option to select the table to the user and the gridview should display data from that table.

I used some help from stackoverflow.

  <telerik:RadGridView ItemsSource="{Binding TableData}" AutoGenerateColumns="True"/>

and a extension method for data reader

        public static IEnumerable<dynamic> AsEnumerable(this System.Data.IDataReader source)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            var columns = Enumerable.Range(0, source.FieldCount).Select(source.GetName).ToList();

            while (source.Read())
            {
                
                dynamic dRow = new ExpandoObject();
                foreach (var column in columns)
                {
                    ((IDictionary<string, object>)dRow).Add(column, source[column]);
                }
                yield return dRow;
            }
        }

and bind it to the ObservableCollection. That’s it.

WPF TemplateSelector for contentTemplate

I wanted to dynamically change template of the tab content based on the tab selected. I used ContentTemplateSelector. It’s so simple:
Write a custom template selector inheriting DataTemplateSelector and override SelectTemplate method

    public class CustomTabItemSelector
        : DataTemplateSelector
    {
        public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
        {
            FrameworkElement element = container as FrameworkElement;
            if (element != null && item != null && item is object)
            {
                if (item.ToString().ToLower() == "related" || item.ToString().ToLower() == "linked")
                    return element.FindResource("TabContentQuestionDetails") as DataTemplate;
                else if(item.ToString().ToLower() == "comments")
                    return element.FindResource("TabContentComments") as DataTemplate;
                else
                    return element.FindResource("TabContentAnswers") as DataTemplate;
                
            }
            return null;
        }
    }

You need to declare DataTemplates in the ResourceDictionary or in the window resources or any where the element can be able to find the resource

    <DataTemplate x:Key="TabContentQuestions">
            <telerik:RadGridView
                             ItemsSource="{Binding DataContext.Questions, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
                             Height="300" Width="Auto"
                             AutoGenerateColumns="False"
                            x:Name="QuestionGrid" AllowDrop="False"
                             >
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn Header="Title" DataMemberBinding="{Binding Title}"/>
                </telerik:RadGridView.Columns>
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                        <i:InvokeCommandAction Command="{Binding DataContext.SelectedQuestionCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding ElementName=QuestionGrid, Path=SelectedItem}">

                        </i:InvokeCommandAction>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </telerik:RadGridView>
        </DataTemplate>

you need to add the reference to the customtemplateselector assembly and declare it in the xaml

//refering the assembly
 xmlns:ts="clr-namespace:SomeAssemblyNamespace;assembly:SomeReferencingAssemblyName"

//Declare the customselector
<ts:CustomTabItemSelector x:Key="myCustomTabItemSelector"/>

//Using the selector in the tabcontrol
<telerik:RadTabControl x:Name="SomeTab"
                       ContentTemplateSelector="{StaticResource myCustomTabItemSelector}"

Alternate row colors for WPF ListView

To set the alternate background colors for the listview in WPF, set the style and then refer that style object in the listview

  <Style x:Key="ListViewAlternateColors" TargetType="ListViewItem">
            <Style.Triggers>
                <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                    <Setter Property="Background" Value="Gray" />
                </Trigger>
                <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                    <Setter Property="Background" Value="LightGoldenrodYellow" />
                </Trigger>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="White" />
                </Trigger>
                
            </Style.Triggers>
        </Style>

and then set the style to the listview

 <ListView Height="170" ItemContainerStyle="{StaticResource ListViewAlternateColors}" Name="listView1" Width="719" AlternationCount="2" SelectionChanged="listView1_SelectionChanged" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Title}" />    
                    </StackPanel>
                    
                </DataTemplate>
            </ListView.ItemTemplate>
            
        </ListView>

Hope this helps someone.