簡體   English   中英

WPF DataGrid - 從 DataGrid ItemsSource 對象的集合值中設置每行(對象)唯一的 combobox 值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM