WPF DataGrid - 从 DataGrid ItemsSource 对象的集合值中设置唯一的每行(对象)组合框值
Posted
技术标签:
【中文标题】WPF DataGrid - 从 DataGrid ItemsSource 对象的集合值中设置唯一的每行(对象)组合框值【英文标题】:WPF DataGrid - Set unique per row (object) combobox values from the DataGrid ItemsSource object's collection value 【发布时间】:2021-05-01 22:15:52 【问题描述】:我正在尝试根据行(对象)的单个集合值设置列组合框值,以便每一行具有基于另一个值的不同选项列表。
例如。
第 1 列:国家/地区组合框 - 例如英国选自 "UK", "USA", "France"
第 2 列:城市组合框 - 例如LA selected "New York", "LA", "Texas" (基于 USA 之前的选择)
下面是我的示例数据对象
public class ExampleData
public List<string> countries get; set;
public List<string> cities get; set;
public string country get; set;
public string city get; set;
public ExampleData(string country)
this.country = country;
countries = new List<string>() "UK", "USA", "France" ;
// Example update method to change dependant options
public void UpdateOptions()
if (country == "UK")
cities = new List<string>() "London", "Bristol", "Birmingham" ;
else if (country == "USA")
cities = new List<string>() "New York", "LA", "Texas" ;
else if (country == "France")
cities = new List<string>() "Paris", "Lyon", "Nice" ;
else
cities = new List<string>();
然后我会创建一个数据的示例集合,以显示在数据网格中
public void TestScenario()
ExampleDataCollection = new List<ExampleData>();
exampleDataList.Add(new ExampleData("UK"));
exampleDataList.Add(new ExampleData("USA"));
exampleDataList.Add(new ExampleData("France"));
DataGrid.ItemsSource = ExampleDataCollection ;
然后在 xaml 中,我会将对象集合作为 ItemsSource 绑定到数据网格,而每个列组合框将绑定到对象自己的集合,该集合将是每行(对象)独立的。这类似于 ExampleData.countries,其中 ExampleData.Country 是选定的值。
<DataGrid
Name="ExampleDataGrid"
AutoGenerateColumns="False"
ItemsSource="Binding ExampleDataCollection"
>
<DataGrid.Columns>
<DataGridComboBoxColumn
Header="country"
ItemsSource="Binding ExampleData.countries"
SelectedValueBinding="Binding ExampleData.country"
/>
<DataGridComboBoxColumn
Header="city"
ItemsSource="Binding ExampleData.cities"
SelectedValueBinding="Binding ExampleData.city"
/>
</DataGrid.Columns>
</DataGrid>
这实际上是否可行,或者是否应该将替代方法应用于这种情况?从逻辑上讲,这并不是一个复杂的过程,但是我一直无法实施解决方案。
【问题讨论】:
【参考方案1】:以经典形式,我几乎放弃后不久就解决了这个问题!
解决方案是将对象集合绑定到主窗口类中的数据网格,然后绑定国家、国家、城市和城市的各个属性。这还包括为相关下拉列表添加更新触发器,以便可以调用类中的更新方法。
<DataGrid
Name="ExampleDataGrid"
AutoGenerateColumns="False"
>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Country">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="Binding countries" SelectedItem="Binding Country, UpdateSourceTrigger=PropertyChanged"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="city">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="Binding cities" SelectedItem="Binding City, UpdateSourceTrigger=PropertyChanged"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
国家和城市的字符串列表已更新为可观察的集合,以便新的组合框在更改时更新它们。添加 INotifyPropertyChanged 意味着当国家或城市从绑定到它的下拉选择中更改时,它会调用 OnPropertyChanged 方法。
这让我可以调用另一个方法来更新新的城市列表。必须注意的是,您不能简单地通过 equals 将现有集合替换为新集合。它必须具有与之相关的更改,例如添加或删除(不清楚)才能实际更新。见下文。
public class ExampleData : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<string> countries get; set;
public ObservableCollection<string> cities get; set;
public ObservableCollection<string> towns get; set;
private string country;
private string city;
private string town;
public string Country
get
return country;
set
country = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("Country");
public string City
get
return city;
set
city = value;
public string Town get; set;
public ExampleData(string country)
this.country = country;
countries = new ObservableCollection<string>() "UK", "USA", "France" ;
cities = new ObservableCollection<string>() "London", "Bristol", "Plymouth" ;
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
UpdateOptions();
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
public void UpdateOptions()
List<string> oldCities = cities.ToList<string>();
List<string> newCities;
foreach (string city in oldCities)
cities.Remove(city);
if (country == "UK")
newCities = new List<string>() "London", "Bristol", "Birmingham" ;
else if (country == "USA")
newCities = new List<string>() "New York", "LA", "Texas" ;
else if (country == "France")
newCities = new List<string>() "Paris", "Lyon", "Nice" ;
else
newCities = new List<string>();
foreach (string city in newCities)
cities.Add(city);
主窗口代码未做任何更改,如下所示。
public partial class MainWindow : Window
public List<ExampleData> exampleDataList;
public MainWindow()
InitializeComponent();
TestScenario();
public void TestScenario()
exampleDataList = new List<ExampleData>();
exampleDataList.Add(new ExampleData("UK"));
exampleDataList.Add(new ExampleData("USA"));
exampleDataList.Add(new ExampleData("France"));
ExampleDataGrid.ItemsSource = exampleDataList;
【讨论】:
太棒了。祝你好运以上是关于WPF DataGrid - 从 DataGrid ItemsSource 对象的集合值中设置唯一的每行(对象)组合框值的主要内容,如果未能解决你的问题,请参考以下文章
从 WPF DataGrid 中的按钮触发 RelayCommand
使用 MVVM 从 WPF 中的 TextBox 进行正确的 DataGrid 搜索
WPF DataGrid - 从 DataGrid ItemsSource 对象的集合值中设置唯一的每行(对象)组合框值