How do I make a WPF DataGridColumn a bound, editable ComboBox where changes to the items are propagated to other rows?

  Kiến thức lập trình

I’m using a WPF DataGrid bound to a collection. One of the columns will be a ComboBox. I want the ComboBox to be editable, and also any changes to the text to be propagated to all other items in the collection that were previously using the same value.

Here is my XAML:

<Window x:Class="WpfApp1.MainWindow"
        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:WpfApp1"
        mc:Ignorable="d"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="450" Width="800">
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Students}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" />
            <DataGridTemplateColumn Header="Favorite Color">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox IsEditable="True" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Colors}" Text="{Binding FavoriteColor}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Window>

and here is my code:

public class Student : INotifyPropertyChanged
{
    private string favoriteColor;

    public string Name { get; set; }
    public string FavoriteColor
    {
        get { return favoriteColor; }
        set
        {
            favoriteColor = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("FavoriteColor"));
        }
    }

    public Student(string name, string favoriteColor)
    {
        Name = name;
        this.favoriteColor = favoriteColor;
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public partial class MainWindow : Window
{
    public ObservableCollection<Student> Students { get; set; } = new ObservableCollection<Student>(new Student[] { new Student("Alice", "Red"), new Student("Bob", "Blue"), new Student("Craig", "Blue") });
    public List<string> Colors { get; set; } = new List<string>();

    public MainWindow()
    {
        InitializeComponent();

        Colors.AddRange(Students.Select(x => x.FavoriteColor).Distinct());
    }
}

So for example, if Craig’s favorite color is changed to “BlueGreen”, Bob’s should update simultaneously:

I got pretty close by handling the ComboBox.TextBoxBase.TextChanged event, but it was getting complicated enough to make me think there must be a more straightforward way.

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT