使用另一列中的值填充DataGrid的ComboBox

时间:2022-09-25 08:58:38

I am an experienced user of Winforms and I am now playing with WPF, but I am struggling a bit. I have a datagrid with 2 columns. The first column is a DataGridTextColumn which is bound to the "Name" property of my object. The second column is bound to the "Power" property of my object.

我是Winforms的有经验的用户,我现在正在玩WPF,但我有点挣扎。我有一个包含2列的数据网格。第一列是DataGridTextColumn,它绑定到我的对象的“Name”属性。第二列绑定到我的对象的“Power”属性。

When the user edits the Power column, I would like to display a combo box that lists all the Name of the first column in addition of "None" as first item. How can I do that?

当用户编辑Power列时,我想显示一个组合框,其中列出了第一列的所有Name以及“None”作为第一项。我怎样才能做到这一点?

In addition, if the user updates any Name of the first column, I would like the change to be reflected in the Power column. Is it possible?

此外,如果用户更新第一列的任何名称,我希望更改反映在“电源”列中。可能吗?

In code behind:

代码背后:

public partial class MainWindow : Window
{
    ObservableCollection<MyObject> objects = new ObservableCollection<MyObject>();

    public MainWindow()
    {
        InitializeComponent();
        dgObjects.ItemsSource = objects;
    }
}

public class MyObject
{   
    public String Name { get; set; }
    public String Power { get; set; }
}

In Xaml:

在Xaml中:

<DataGrid Name="dgObjects" AutoGenerateColumns="False">
   <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        <DataGridComboBoxColumn Header="Power" Binding="????"/>
    </DataGrid.Columns>
</DataGrid>

Thanks

谢谢

1 个解决方案

#1


0  

You can do this via binding on the DataContext. Though, first you need to set up the Window's DataContext properly. ItemsSource should not be done via code-behind (this is WPF, use binding!).

您可以通过绑定DataContext来完成此操作。但是,首先需要正确设置Window的DataContext。 ItemsSource不应该通过代码隐藏完成(这是WPF,使用绑定!)。

Set up your class structure like:

设置类结构,如:

  public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new ViewModel();
        }
    }

    public class ViewModel
    {
        public ObservableCollection<MyObject> Objects { get; } = new ObservableCollection<MyObject>();

        public ViewModel()
        {
            Objects.Add(new MyObject
            {
                Name = "Name"
            });
            Objects.Add(new MyObject
            {
                Name = "Name2"
            });
            Objects.Add(new MyObject
            {
                Name = "Name3"
            });
        }
    }

    public class MyObject
    {
        public String Name { get; set; }
        public String Power { get; set; }
    }

Now, update your xaml. You will need to use a CellTemplate and a standard Combobox. The ComboBox will then bind to the Objects collection, display the Name, but set the value in Power.

现在,更新你的xaml。您需要使用CellTemplate和标准Combobox。然后,ComboBox将绑定到Objects集合,显示Name,但在Power中设置值。

<Window x:Class="WpfApplication8.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"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        x:Name="MyWindow">
    <Grid>
        <DataGrid Name="dgObjects" AutoGenerateColumns="False"
                  ItemsSource="{Binding Objects}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding ElementName=MyWindow, Path=DataContext.Objects}" 
                                      DisplayMemberPath="Name"
                                      SelectedItem="{Binding Power}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

#1


0  

You can do this via binding on the DataContext. Though, first you need to set up the Window's DataContext properly. ItemsSource should not be done via code-behind (this is WPF, use binding!).

您可以通过绑定DataContext来完成此操作。但是,首先需要正确设置Window的DataContext。 ItemsSource不应该通过代码隐藏完成(这是WPF,使用绑定!)。

Set up your class structure like:

设置类结构,如:

  public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new ViewModel();
        }
    }

    public class ViewModel
    {
        public ObservableCollection<MyObject> Objects { get; } = new ObservableCollection<MyObject>();

        public ViewModel()
        {
            Objects.Add(new MyObject
            {
                Name = "Name"
            });
            Objects.Add(new MyObject
            {
                Name = "Name2"
            });
            Objects.Add(new MyObject
            {
                Name = "Name3"
            });
        }
    }

    public class MyObject
    {
        public String Name { get; set; }
        public String Power { get; set; }
    }

Now, update your xaml. You will need to use a CellTemplate and a standard Combobox. The ComboBox will then bind to the Objects collection, display the Name, but set the value in Power.

现在,更新你的xaml。您需要使用CellTemplate和标准Combobox。然后,ComboBox将绑定到Objects集合,显示Name,但在Power中设置值。

<Window x:Class="WpfApplication8.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"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        x:Name="MyWindow">
    <Grid>
        <DataGrid Name="dgObjects" AutoGenerateColumns="False"
                  ItemsSource="{Binding Objects}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding ElementName=MyWindow, Path=DataContext.Objects}" 
                                      DisplayMemberPath="Name"
                                      SelectedItem="{Binding Power}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>