简体   繁体   中英

How to Dynamically change Datagrid Columns in xaml

Using the WPF DataGrid, I would like be able to change the columns displayed in xaml based on a property on the ViewModel.

The Idea is simply to change the set of Columns based on a property on the ViewModel. The various Views have columns in different combinations and all in different orders.

This should be trivial I thought but I can not find examples of where this has been done before

Any help would be appreciated. Thanks.

At it's simplest:

Xaml

<Window 
x:Class="Sample.MainWindow" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 


Title="MainWindow" 
Height="350" 
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Width="700">
<Window.Resources>

</Window.Resources>
<Grid>

    <DataGrid
        x:Name="grid"
        ItemsSource="{Binding Persons}"
        AutoGenerateColumns="False">

        <!-- If Mode = City then 
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            <DataGridTextColumn Header="City" Binding="{Binding FavouriteCity}"/>
        </DataGrid.Columns>
        -->

        <!-- If Mode = Colour then -->
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            <DataGridTextColumn Header="Colour" Binding="{Binding FavouriteColour}"/>
        </DataGrid.Columns>
    </DataGrid>

</Grid>
</Window>

Code

namespace Sample {
public partial class MainWindow: INotifyPropertyChanged
{

    public ObservableCollection<Person> Persons { get; set; }
    public string Mode { get; set; }

    public MainWindow() {
        InitializeComponent();


        Persons = new ObservableCollection<Person>()
        {       new Person("John","Yellow","Paris"),
                new Person("Anne","Green","Lagos"),
                new Person("James","Pink","Brussels")
        };
        Mode = "City";
        OnPropertyChanged("Persons");
        OnPropertyChanged("Mode");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class Person 
{
    public string Name { get; set; }
    public string FavouriteColour { get; set; }
    public string FavouriteCity { get; set; }

    public Person(string name, string favouriteColour, string favouriteCity)
    {
        Name = name;
        FavouriteColour = favouriteColour;
        FavouriteCity = favouriteCity;
    }    }    }

There are many approaches to this I am sure, but the first thing I thought of was the VisualStateManager. See the MSDN here . You might start by reading the remarks at the bottom of that page - excerpted:

The VisualStateManager enables you to specify states for a control, the appearance of a control when it is in a certain state, and when a control changes states.

A caveat here is that I have not actually used the VSM yet; I merely came across it while answering another person's question. You may find his question to be an instructive example: Changing GridView Item height using VSM Triggers

The description of this class' purpose matches your use case though, and your implementation seems like a relatively straightforward extension of VSM examples.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM