繁体   English   中英

更改另一个组合框selecteditem时更改组合框项目吗?

[英]Change combobox items when another combobox selecteditem changed?

我在视图中有两个ComboBox 我想在更改第一个selecteditem时更改第二个itemsources:

风景:

<ComboBox ItemsSource="{Binding ProductsList}" SelectedValue="{Binding SelectedProduct}" DisplayMemberPath="ChipName"/>

ViewModel:

    public MainViewModel()
    {
        GetProductsList();
    }

    ProductDb pd = new ProductDb();
    public ObservableCollection<Product> ProductsList { get; set; }
    private void GetProductsList()
    {
        try
        {
            ProductsList = new ObservableCollection<Product>(pd.GetProducts());
        }
        catch(Exception e) { Console.WriteLine(e.ToString()); }
        if (ProductsList != null) SelectedProduct = ProductsList[0];
    }

该模型从xml读取数据:

public class ProductDb
{
    public ObservableCollection<Product> GetProducts()
    {
        ObservableCollection<Product> _products = new ObservableCollection<Product>();
        XDocument doc = XDocument.Load(@".\Config\Chip.xml");
        foreach(XElement productRow in doc.Root.Elements("Chip"))
        {
            var p = new Product(productRow.Element("ChipName").Value, productRow.Element("Series").Value, productRow.Element("Type").Value,
                Convert.ToUInt32(productRow.Element("FlashAddress").Value), Convert.ToUInt32(productRow.Element("PageCount").Value), Convert.ToUInt32(productRow.Element("PageSize").Value),
                Convert.ToUInt32(productRow.Element("RAMAdd").Value, 16), Convert.ToUInt32(productRow.Element("RAMLength").Value, 16), productRow.Element("Crystals").Value);

            foreach (XElement crystal in productRow.Element("Crystals").Elements())
            {
                p.Crystals.Add(crystal.Value);
            }
            _products.Add(p);
        }
        return _products;
    }
}

现在,上面的代码填充了第一个组合框中的ChipName ,我想在第二个组合框中显示SelectedProduCraystal 我应该怎么做? 提前致谢!

- 更新: -

水晶是产品的元素。 它包含几个水晶。 xml文件如下所示:

<System>
  <Chip>
    <ChipName>Hxxxxxxx</ChipName>
    <Series>CM0+</Series>
    <Type>0</Type>
    <FlashAddress>00000000</FlashAddress>
    <PageCount>256</PageCount>
    <PageSize>512</PageSize>
    <RAMAdd>20000000</RAMAdd>
    <RAMLength>0x1800</RAMLength>
    <Crystals>
      <Crystal>4</Crystal>
      <Crystal>6</Crystal>
      <Crystal>8</Crystal>
      <Crystal>10</Crystal>
      <Crystal>12</Crystal>
      <Crystal>16</Crystal>
      <Crystal>18</Crystal>
      <Crystal>20</Crystal>
      <Crystal>24</Crystal>
      <Crystal>32</Crystal>
    </Crystals>
  </Chip>
</System>

就像您已经拥有的产品一样,但是需要告诉UI在哪里可以找到新组合的新商品来源:

XAML:

  <ComboBox ItemsSource="{Binding Crystals}" 
            SelectedValue="{Binding SelectedCrystal}" 
            DisplayMemberPath="CrystalName"/>

C#:

public Product SelectedProduct
{
  set 
    {
       // your private member setting...
       // raise property change for crystal collection for UI to respond
    }
}

public Product SelectedCrystal
{
  set 
  {
     // your private member setting...
     // raise property change for crystal collection for UI to respond
  }
}

public ObservableCollection<Crystal> Crystals
{
  get 
    {
       if (SelectedProduct != null)
         return SelectedProduct.Crystals;

       return new ObservableCollection<Crystal>();
    }
}

如果愿意,还可以根据绑定控件集合中是否存在任何有效对象,来控制水晶控件的可见性或启用状态。

如果您实现INotifyPropertyChanged接口并引发SelectedProduct属性的PropertyChanged事件,则此方法应该起作用:

<ComboBox ItemsSource="{Binding SelectedProduct.Crystals}" />

如果CrystalsProduct类的公共属性,那么这也应该起作用:

<ComboBox x:Name="a" ItemsSource="{Binding ProductsList}"
                  SelectedValue="{Binding SelectedProduct}"
                  DisplayMemberPath="ChipName"/>

<ComboBox x:Name="b" ItemsSource="{Binding SelectedItem.Crystals, ElementName=a}" />

xaml:

<ComboBox ItemsSource="{Binding ProductsList}" SelectedItem="{Binding SelectedProduct,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="ChipName"/>
<ComboBox ItemsSource="{Binding Crystals}" />

C#:

public class MainModel:INotifyPropertyChanged    
{   
        event PropertyChangedEventHandler PropertyChanged;  
        ObservableCollection<Product> _ProductsList = null;  
        ObservableCollection<Crystal> Crystals = null;  
        Product _SelectedProduct = null;

    public ObservableCollection<Product> ProductsList   
    {
        get
        {
            return _ProductsList;
        } 
        set
        {
            _ProductsList=value;
            PropertyChanged?.Invoke(this,new System.ComponentModel.PropertyChangedEventArgs("ProductsList")); 
        }
    }  

    public ObservableCollection<Crystal> Crystals    
    {
        get
        {
            return _Crystals;
        } 
        set
        {
            _Crystals=value;
            PropertyChanged?.Invoke(this,new System.ComponentModel.PropertyChangedEventArgs("Crystals")); 
        }
    } 

    public Product SelectedProduct
    {
        get
        {
            return _SelectedProduct;
        }
        set
        {
            _SelectedProduct = value;
            PropertyChanged?.Invoke(this,new System.ComponentModel.PropertyChangedEventArgs("SelectedProduct")); 
            ResetCrystals();
        }
    } 
    private void ResetCrystals()
    {
         Crystals=.....
    }
}

您是否尝试过这样的事情:

<StackPanel>
        <ComboBox Width="100" Height="22" ItemsSource="{Binding ProductsList}" SelectedValue="{Binding SelectedProduct}" DisplayMemberPath="ChipName"/>
        <ComboBox Width="100" Height="22" ItemsSource="{Binding SelectedProduct.Crystals}"  DisplayMemberPath="Value"/>    
</StackPanel>

对我来说,这很好,我只是将Product.Crystals设置为ObservableCollection,并使用INotifyPropertyChanged接口进行了SelectedProduct

例如:视图模型:

        public ObservableCollection<Product> ProductsList { set; get; }
        public Product SelectedProduct
        {
            set
            {
                _selectedProduct = value;
                NotifyPropertyChanged();
            }
            get
            {
                return _selectedProduct;
            }
        }

模型:

public class Product
    {
        public ObservableCollection<Crystal> Crystals { set; get; }
        public String ChipName { set; get; }
        public Product(ObservableCollection<Crystal> l, String ChipName)
        {
            this.ChipName = ChipName;
            Crystals = l;
        }
    }

    public class Crystal
    {
        public string Value { set; get; }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM