WPF FAQ - ListView

Find answers for the most frequently asked questions
Expand All Collapse All

You can do so by first defining a DataTemplate for the corresponding columns as follows. Sample code can be seen with better formatting in this thread (ListView Column ToolTip)

[XAML]
<Page xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
      xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
    <StackPanel>
        <StackPanel.Resources>
            <DataTemplate x:Key='nameTemplate'>
                <TextBlock Text='{Binding Name}'  Margin='-6,0'>
                    <TextBlock.ToolTip>
                        <ToolTip>
                            <TextBlock Foreground='Green' Text='{Binding Name}'/>
                        </ToolTip>
                    </TextBlock.ToolTip>
                </TextBlock>
            </DataTemplate>
            <DataTemplate x:Key='namespaceTemplate'>
                <TextBlock Text='{Binding Namespace}'  Margin='-6,0'>
                    <TextBlock.ToolTip>
                        <ToolTip>
                            <TextBlock Foreground='Green' Text='{Binding Namespace}'/>
                        </ToolTip>
                    </TextBlock.ToolTip>
                </TextBlock>
            </DataTemplate>
        </StackPanel.Resources>
        <ListView>
            <ListView.ItemContainerStyle>
                <Style TargetType='ListViewItem'>
                    <Setter Property='HorizontalContentAlignment' Value='Stretch'/>
                    <Setter Property='VerticalContentAlignment' Value='Stretch'/>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView>
                    <GridViewColumn CellTemplate='{StaticResource nameTemplate}' Width='300' Header='Name'/>
                    <GridViewColumn CellTemplate='{StaticResource namespaceTemplate}' Width='300' Header='Namespace'/>
                </GridView>
            </ListView.View>
            <x:Type TypeName='Visual'/>
            <x:Type TypeName='FrameworkElement'/>
            <x:Type TypeName='FrameworkContentElement'/>
        </ListView>
    </StackPanel>
</Page>
Permalink

You can do so as follows:

[C#]
            this.myList.SelectedItem = o;
            // In case the item is out of view. If so, the next line could cause an exception without bringing this item to view.
            myList.ScrollIntoView(this.myList.SelectedItem);
            ListViewItem lvi = (ListViewItem)myList.ItemContainerGenerator.ContainerFromIndex(myList.SelectedIndex);
            lvi.Focus();
Permalink

The following utility class (provided in this thread: Accessing and Mondifying DataTemplate Element Runtime for CellTemplate should help you achieve this:

[C#]
    public static class ListViewHelper 
    { 
        public static FrameworkElement GetElementFromCellTemplate(ListView listView, Int32 column, Int32 row, String name) 
        { 
            if (row >= listView.Items.Count || row < 0) 
            { 
                throw new ArgumentOutOfRangeException('row'); 
            } 
            GridView gridView = listView.View as GridView; 

            if (gridView == null) { return null; } 
            
            if (column >= gridView.Columns.Count || column < 0) 
            { 
                throw new ArgumentOutOfRangeException('column'); 
            } 
            
            ListViewItem item = listView.ItemContainerGenerator.ContainerFromItem(listView.Items[row]) as ListViewItem; 
            
            if (item != null) 
            { 
                GridViewRowPresenter rowPresenter = GetFrameworkElementByName(item); 
                
                if (rowPresenter != null) 
                { 
                    ContentPresenter templatedParent = VisualTreeHelper.GetChild(rowPresenter, column) as ContentPresenter; 
                    DataTemplate dataTemplate = gridView.Columns[column].CellTemplate; 
                    if (dataTemplate != null && templatedParent != null) 
                    { 
                        return dataTemplate.FindName(name, templatedParent) as FrameworkElement; 
                    } 
                } 
            } 
            return null; 
        } 
        private static T GetFrameworkElementByName(FrameworkElement referenceElement) where T : FrameworkElement 
        { 
            FrameworkElement child = null; 
            
            for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(referenceElement); i++) 
            { 
                child = VisualTreeHelper.GetChild(referenceElement, i) as FrameworkElement; 
                System.Diagnostics.Debug.WriteLine(child); 
                if (child != null && child.GetType() == typeof(T)) 
                { 
                    break; 
                } 
                else if (child != null) 
                { 
                    child = GetFrameworkElementByName(child); 
                    if (child != null && child.GetType() == typeof(T)) 
                    { 
                        break; 
                    } 
                } 
            } 
            return child as T; 
        } 
    }
Permalink

Here is a solution:

[XAML]
<Page

    xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'

    xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'

    xmlns:sys='clr-namespace:System;assembly=mscorlib'>

  <Page.Resources>

    <XmlDataProvider x:Key='CharacterData'>

      <x:XData>

        <Data xmlns=''>

          <Character First='Bart' Last='Simpson' Gender='M'/>

          <Character First='Homer' Last='Simpson' Gender='M'/>

          <Character First='Lisa' Last='Simpson' Gender='F'/>

          <Character First='Maggie' Last='Simpson' Gender='F'/>

          <Character First='Marge' Last='Simpson' Gender='F'/>

        </Data>

      </x:XData>

    </XmlDataProvider>

    <DataTemplate x:Key='LVTSimpleText'>

      <Border Width='Auto' Height='Auto' BorderBrush='#FF000000' 

          BorderThickness='0,0,2,2'>

        <TextBox Width='Auto' Height='Auto' Text='{Binding Value}' 

            TextWrapping='Wrap'/>

      </Border>

    </DataTemplate>

  </Page.Resources>

  <ListView ItemsSource='{Binding Source={StaticResource CharacterData},

      XPath=Data/Character}'>

    <ListView.View>

      <GridView>

        <GridViewColumn Header='First Name'>

          <GridViewColumn.CellTemplate>

            <DataTemplate>

              <ContentControl Content='{Binding XPath=@First}' 

                  ContentTemplate='{StaticResource LVTSimpleText}' />

            </DataTemplate>

          </GridViewColumn.CellTemplate>

        </GridViewColumn>

        <GridViewColumn Header='Last Name'>

          <GridViewColumn.CellTemplate>

            <DataTemplate>

              <ContentControl Content='{Binding XPath=@Last}' 

                  ContentTemplate='{StaticResource LVTSimpleText}' />

            </DataTemplate>

          </GridViewColumn.CellTemplate>

        </GridViewColumn>

        <GridViewColumn Header='Gender'>

          <GridViewColumn.CellTemplate>

            <DataTemplate>

              <ContentControl Content='{Binding XPath=@Gender}' 

                  ContentTemplate='{StaticResource LVTSimpleText}' />

            </DataTemplate>

          </GridViewColumn.CellTemplate>

        </GridViewColumn>

      </GridView>

    </ListView.View>

  </ListView>

</Page>


Permalink

This is kind of how Firefox lets you search texts – as you type in the search box the matching text all get highligted automatically. You can use this solution for other templatized controls as well.

(For better formatting, take a look at this thread: How to color particular cell of the grid view?)

[XAML]
<Window x:Class='SDKSample.Window1'  
    xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'  
    xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'  
    Loaded='OnLoad'  
    xmlns:ds='clr-namespace:SDKSample'>   
    
  <Window.Resources>  
        <ds:MyBGConverter x:Key='myBGConverter'></ds:MyBGConverter>  
            <ObjectDataProvider x:Key='EmployeeInfoDataSource'  
           ObjectType='{x:Type ds:myEmployees}'/>   
      <!--Repeat this for all columns where you want this to happen-->  
        <DataTemplate x:Key='myCellTemplateFN'>   
          <DockPanel>  
            <TextBlock Foreground='Green' HorizontalAlignment='Center'>   
              <TextBlock.Text>  
                <Binding Path='FirstName'/>   
              </TextBlock.Text>  
                <TextBlock.Background>  
                    <MultiBinding Converter='{StaticResource myBGConverter}'>   
                        <MultiBinding.Bindings>  
                            <Binding ElementName='searchTB' Path='Text' />  
                            <Binding RelativeSource='{RelativeSource Self}'></Binding>  
                        </MultiBinding.Bindings>  
                    </MultiBinding>  
                </TextBlock.Background>  
            </TextBlock>  
          </DockPanel>  
        </DataTemplate>  
  
    </Window.Resources>  
  <Grid>  
    <Grid.RowDefinitions>  
      <RowDefinition Height='50'/>   
      <RowDefinition/>  
    </Grid.RowDefinitions>  
    <Grid.ColumnDefinitions>  
      <ColumnDefinition/>  
      <ColumnDefinition/>  
    </Grid.ColumnDefinitions>  
    <TextBlock Grid.Row='0' Grid.Column='0' FontSize='14'  
               HorizontalAlignment='Center'>   
      ListView created with XAML   
    </TextBlock>  
    <StackPanel Grid.Row='1' Grid.Column='0' HorizontalAlignment='Center'>   
      <ListView ItemsSource='{Binding Source=   
                             {StaticResource EmployeeInfoDataSource}}'   
                >  
        <ListView.View>  
          <GridView AllowsColumnReorder='true'  
                    ColumnHeaderToolTip='Employee Information'>   
            <GridViewColumn CellTemplate='{StaticResource myCellTemplateFN}'  
                            Header='First Name' Width='100'/>   
            <GridViewColumn DisplayMemberBinding=   
                                '{Binding Path=LastName}'    
                            Header='Last Name' Width='100'/>   
            <GridViewColumn DisplayMemberBinding=   
                                '{Binding Path=EmployeeNumber}'    
                            Header='Employee No.' Width='100'/>   
          </GridView>  
        </ListView.View>  
      </ListView>  
            <StackPanel Orientation='Horizontal'>   
                <TextBlock>Enter Search String Here:</TextBlock>  
                <TextBox x:Name='searchTB' MinWidth='100' Width='150'></TextBox>  
            </StackPanel>  
        </StackPanel>  
  </Grid>  
  
</Window>  

And add this to your code-behind:

[C#]
public class MyBGConverter : IMultiValueConverter   
    {  
        #region IMultiValueConverter Members   
  
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)   
        {   
            TextBlock lvi = (TextBlock)values[1];   
            string filter = (string)values[0];   
            if (filter != String.Empty && lvi.Text.ToLower().Contains(filter.ToLower()))   
            {   
                return Brushes.Aqua;   
            }   
            else  
                return Brushes.White;   
        }   
  
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)   
        {   
            throw new NotImplementedException();   
        }  
 
        #endregion   
    }   
  
    public class EmployeeInfo   
    {   
        private string _firstName;   
        private string _lastName;   
        private string _employeeNumber;   
  
        public string FirstName   
        {   
            get {return _firstName;}   
            set {_firstName = value;}   
        }   
  
        public string LastName   
        {   
            get {return _lastName;}   
            set {_lastName = value;}   
        }   
  
        public string EmployeeNumber   
        {   
            get {return _employeeNumber;}   
            set {_employeeNumber = value;}   
        }   
  
        public EmployeeInfo(string firstname, string lastname, string empnumber)   
        {   
            _firstName = firstname;   
            _lastName = lastname;   
            _employeeNumber = empnumber;   
        }   
    }   
    public class myEmployees :   
            ObservableCollection   
    {   
        public myEmployees()   
        {   
            Add(new EmployeeInfo('Jesper', 'Aaberg', '12345'));   
            Add(new EmployeeInfo('Dominik', 'Paiha', '98765'));   
            Add(new EmployeeInfo('Yale', 'Li', '23875'));   
            Add(new EmployeeInfo('Muru', 'Subramani', '49392'));   
        }   
    }  
Permalink

Share with

Couldn't find the FAQs you're looking for?

Please submit your question and answer.