[英]WPF change datagrid combobox ItemsSource to value of another datagrid combox
[英]WPF DataGrid - Set unique per row (object) combobox values from the DataGrid ItemsSource object's collection value
我正在嘗試根據行(對象)的單個集合值設置列 combobox 值,以便每一行具有基於另一個值的不同選項列表。
例如。
第 1 列:國家 combobox - 例如,從 {“UK”、“USA”、“France”} 中選擇的 UK
第 2 列:城市 combobox - 例如 LA 選擇 {“New York”、“LA”、“Texas”}(基於之前的 USA 選擇)
下面是我的示例數據 object
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 中,我將 object 集合綁定到數據網格作為 ItemsSource,而每一列 combobox 將綁定到對象自己的集合,每行獨立(對象)。 這類似於 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>
這實際上是否可行,或者是否應該將替代方法應用於這種情況? 從邏輯上講,這並不是一個復雜的過程,但是我一直無法實施解決方案。
以經典形式,我幾乎放棄后不久就解決了這個問題!
解決方案是將 object 集合綁定到主 window class 內的數據網格,然后綁定國家、國家、城市和城市的各個屬性。 這還包括為相關下拉列表添加更新觸發器,以便可以調用 class 中的更新方法。
<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>
國家和城市的字符串列表更新為可觀察的 collections,以便 combobox 新的更新時更新它們。 添加 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);
}
}
}
主 window 代碼未做任何更改,如下所示。
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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.