Dailycode.info

Short solution for short problems

Combining 2 or more columns in a listview using CellTemplate in stead of DisplayMemberBinding

Combining 2 or more columns in a listview is really simple actually. Using the DisplayMemberBinding

Property won’t get you there. This only allows 1 column to be bound. But using the CellTemplate property, you have unlimited possibilities. Just define the data template in a resource for example and bind it to the CellTemplate property. Here’s a simple example:

 

<GridViewColumn

Header="Country"

DisplayMemberBinding="{Binding Path=Country.CountryName}"

/> 

<GridViewColumn

Header="Farmer"

CellTemplate="{StaticResource FarmerTemplate}"

/>

 

 

The data template is defined in a resource file and looks like this:

 

<DataTemplate x:Key="FarmerTemplate">

    <DockPanel>

        <TextBlock HorizontalAlignment="Left">

            <TextBlock.Text>

            <Binding Path="Farmer.LastName"/>

            </TextBlock.Text>

        </TextBlock>

        <TextBlock Text=" "></TextBlock>

        <TextBlock HorizontalAlignment="Left">

            <TextBlock.Text>

            <Binding Path="Farmer.FirstName"/>

            </TextBlock.Text>

        </TextBlock>

    </DockPanel>

</DataTemplate>

 

The result:

 


Using a listview and the selecteditem with WPF and MVVM. (without touching the code behind)

The default listview by Microsoft for Wpf has no commands available. So how can we capture the selected event without using any of the code behind and still use the default controls by Microsoft.

The solution is this. We will bind the IsSelected property of the list to the IsSelected property of your data object.

<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />

 

If the data objects (Model) that are shown in the list do not have this property, we create a wrapper class the implement the IsSelected property.

One option is to create a partial class of your DTO or model to include the IsSelected property:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.Serialization;

 

namespace Regulatory.Server.DTO

{

    public partial class Country

    {

        public Country()

        {

            this.Created = DateTime.Now;

        }

 

        private bool _isSelected;

 

        [DataMember]

        public bool IsSelected

        {

            get { return _isSelected; }

            set { _isSelected = value; }

        }

    }

}

 

 

 

Last we capture the property changed event of the object and set the selected item in your view model to the model (wrapper class) that has the IsSelected property set to true:

CountryModel countryM = new CountryModel(country);

                countryV.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(countryM_PropertyChanged);

 

public CountryModel SelectedCountry

        { get; set; }

 

void countryM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

        {

            string IsSelected = "IsSelected";

 

            // Make sure that the property name we're referencing is valid.

            // This is a debugging technique, and does not execute in a Release build.

            (sender as CountryModel).VerifyPropertyName(IsSelected);

 

            // When a audio record is selected or unselected, we must let the

            // world know that the TotalSelectedSales property has changed,

            // so that it will be queried again for a new value.

            if (e.PropertyName == IsSelected)

            {

                //We check if its a selected or unselected item.

                if (CountryList.Where(d => d.IsSelected == true).Contains(sender as CountryModel))

                {

                    //If its a selected item, set it as selected item in this class.

                    SelectedCountry = sender as CountryModel;

                }

            }

        }

 

Here you see no item is selected:

 

 

Next you will see that the CanSave and CanDelete react to the selecteditem changed:

 

 

 

public bool CanDeleteCountry

        {

            //Check if a country is selected.

            get { SelectedCountry != null; }

        }