Vinci
Vinci

Reputation: 130

Sorting and alternating ListView

I don't know how to implement functions to my XAML

<Window x:Class="WpfApplicationLAB.HighScore"
        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:local="clr-namespace:WpfApplicationLAB"
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
        mc:Ignorable="d"
        Title="HighScore" Height="300" Width="300">
    <Window.Resources>
        <CollectionViewSource x:Key="SortedItems" Source="{Binding items}">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Result"/>
                <scm:SortDescription PropertyName="Name"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>

    <Grid>
        <ListView Margin="10" Name="lvDataBinding" ItemsSource ="{Binding items}" >
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="Height" Value="40" />
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <TextBlock Text="{Binding Name}" FontWeight="Bold" />
                        <TextBlock Text="  " />
                        <TextBlock Text="{Binding Result}" FontWeight="Bold" />
                    </WrapPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

    </Grid>
</Window>

and C#

   public partial class HighScore : Window
    {
        public HighScore()
        {
            InitializeComponent();
            List<User> items = new List<User>();
            items.Add(new User() { Name = "John Doe", Result = 42 });
            items.Add(new User() { Name = "Jane Doe", Result = 39 });
            items.Add(new User() { Name = "Sammy Doe", Result = 13 });
        }
    }
    public class User
    {
        public string Name { get; set; }

        public int Result { get; set; }

        public override string ToString()
        {
            return this.Name + "   " + this.Result;
        }
    }
}

Tried to implement CollectionView sorting but it's not working, what should I change?

Second thing is that I wanted to alternate background color and font color. I tried also to implement function for alternating from this example: Alternate background color in Listview XAML. But I don't understand Property="ItemsControl.AlternationIndex" Value="0" and

<DataTemplate DataType="system:String">
            <!-- put your data template here -->
</DataTemplate>

How should I implement this?

Upvotes: 2

Views: 171

Answers (1)

Peter Duniho
Peter Duniho

Reputation: 70661

It is not really clear from your question what specifically you're having trouble with. However, the code you posted is wrong in a number of ways:

  1. You don't set a data context nor specify binding sources explicitly.
  2. There is nothing that even has an items property to bind to.
  3. You declare, but do not use, the CollectionViewSource, so it would have no effect in any case.

There is also nothing in the code example that shows how you tried to use AlternationIndex, so it's impossible to say what you did wrong.

All that said, the basic ideas are simple enough. Since you found the example regarding AlternationIndex, I'll take as granted that you also did so for the CollectionViewSource part of your question and simply failed to understand those examples. I am including below a version of your code that addresses all of the issues I mention above, as well as shows one possible way to use AlternationIndex to produce formatting differences per-line in your output:

XAML:

<Window x:Class="TestSO37246528SortAndAlternationIndex.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
        Title="MainWindow" Height="350" Width="525"
        Name="mainWindow">

  <Window.Resources>
    <CollectionViewSource x:Key="SortedItems" Source="{Binding items, ElementName=mainWindow}">
      <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="Result"/>
        <scm:SortDescription PropertyName="Name"/>
      </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
  </Window.Resources>

  <Grid>
    <ListView Margin="10" Name="lvDataBinding"
              ItemsSource ="{Binding Source={StaticResource SortedItems}}"
              AlternationCount="2">
      <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
          <Style.Triggers>
            <Trigger Property="ItemsControl.AlternationIndex" Value="1">
              <Setter Property="Background" Value="LightBlue"/>
            </Trigger>
          </Style.Triggers>
          <Setter Property="Height" Value="40" />
        </Style>
      </ListView.ItemContainerStyle>
      <ListView.ItemTemplate>
        <DataTemplate>
          <WrapPanel>
            <TextBlock Text="{Binding Name}" FontWeight="Bold" />
            <TextBlock Text="  " />
            <TextBlock Text="{Binding Result}" FontWeight="Bold" />
          </WrapPanel>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </Grid>
</Window>

C#:

public partial class MainWindow : Window
{
    public List<User> items { get; private set; }

    public MainWindow()
    {
        items = new List<User>();
        items.Add(new User() { Name = "John Doe", Result = 42 });
        items.Add(new User() { Name = "Jane Doe", Result = 39 });
        items.Add(new User() { Name = "Sammy Doe", Result = 13 });
        InitializeComponent();
    }
}

The User class is as before, so I haven't bothered to include it here.

You'll note in the above the following changes:

  1. I gave the window a name, so that I could use it as a binding source.
  2. I moved the local variable items out of the constructor and made it a property in the class. Note that since I did nothing to produce change notifications, it's also critical that the property be set and the list contents are populated before the InitializeComponent() method.
  3. Rather than binding to the original list, I bind using the CollectionViewSource as the binding source, thus ensuring that the ListView uses the view from the CollectionViewSource.

Please carefully compare the above with your original code, so that you can understand how each of the specific problems was fixed. If you have any questions, please feel free to ask. Be sure to state in clear, precise terms what specifically you're having trouble understanding.

Upvotes: 1

Related Questions