简体   繁体   English

更新组合框MVVM(XAML和C#)

[英]Update combobox MVVM (XAML & C#)

I have a form with 2 combos, among other fields. 我在其他领域中有2个连击的表格。 1 combo is filled with brand names ( cmbMarca ). 1个组合中充满了品牌名称( cmbMarca )。 This combo is filled correctly. 此组合已正确填充。 The other combo ( cmbModelo ) should be filled with models of the selected brand. 其他组合( cmbModelo )应该填充有所选品牌的模型。

My problem is that the combo with models ( cmbModelo ) is not updated when selecting a brand (cmbBrand). 我的问题是,选择品牌(cmbBrand)时,带有模型( cmbModelo )的组合不会更新。 When I select a brand, runs all the code but does not display any item in the combo " cmbModelo " 当我选择一个品牌时,运行所有代码,但在组合“ cmbModelo ”中不显示任何项目

FillingForm.xaml FillingForm.xaml

    <Input:SfComboBox x:Name="cmbMarca"   x:uid="BrandsCombo"
    DisplayMemberPath="marca"
ItemsSource="{Binding MarcasSAT.Marcas}"                                                       SelectedValue="{Binding marca, Mode=TwoWay}"
    SelectedValuePath="marca"     
    Tag="{Binding Path=SelectedMarca, Mode=TwoWay}"                                                     SelectionChanged="cmbMarca_SelectionChanged"/>  

    <Input:SfComboBox x:Name="cmbModelo"    x:uid="ModelosCombo" 
    DisplayMemberPath="modelo"    
    ItemsSource="{Binding ModelosSAT.Modelos}" 
     SelectedValue="{Binding modelo, Mode=TwoWay}"
    SelectedValuePath="modelo" />

FillingForm.CS FillingForm.CS

  private void cmbMarca_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {            
                MarcaViewModel curItem = (MarcaViewModel)cmbMarca.SelectedItem;               
                this.cmbMarca.Tag  = curItem.idMarca;
        } 

FillingViewModel.cs FillingViewModel.cs

public class FillingViewModel : ViewModelBase
{

        private readonly MarcasViewModel marcasSAT = new MarcasViewModel();
        public MarcasViewModel MarcasSAT
        {
            get { return this.marcasSAT; }
        }

        private ModelosViewModel modelosSAT = new ModelosViewModel();
        public ModelosViewModel ModelosSAT
        {
            get
            {
                return this.modelosSAT;
            }
            set
            {
                modelosSAT = value;
                RaisePropertyChanged("ModelosSAT");
            }
        }

        private int _selectedMarca;
        public int SelectedMarca
        {
            get { return _selectedMarca; }
            set 
            {
                _selectedMarca = value;
                RaisePropertyChanged("SelectedMarca");
                modelosSAT.MarcaID = _selectedMarca;           
            }
        }

}

ModelosViewModel.cs ModelosViewModel.cs

 public class ModelosViewModel : ViewModelBase
    {
        private ObservableCollection<ModeloViewModel> modelos;
        public ObservableCollection<ModeloViewModel> Modelos
        {
            get
            {
                return modelos ;
            }
            set
            {
                modelos  = value;
                RaisePropertyChanged("Modelos");
            }
        }

        public ObservableCollection<ModeloViewModel> GetModelos()
        {
            modelos  = new ObservableCollection<ModeloViewModel>();
            using (var db = new SQLite.SQLiteConnection(App.DBPath))
            {
                var query = db.Table<Modelos>().Where(c => c.idMarca == _marcaID);   
                //var query = db.Table<Modelos>();   
                foreach (var _mrc in query)
                {
                    var mrc = new ModeloViewModel()
                    {
                        idMarca  = _mrc.idMarca,
                        idModelo = _mrc.idModelo,
                        modelo   = _mrc.modelo                          
                    };
                    modelos.Add(mrc);
                }
            }
            return modelos ;
        }

        private int _marcaID=0;
        public int MarcaID
        {
            get {
                return _marcaID; 
            }
            set
            {
                _marcaID = value;
                RaisePropertyChanged("MarcaID");
                this.GetModelos();
            }
        }

        //public ModelosViewModel()
        //{           
        //    this.modelos = GetModelos();
        //}

    }

MarcasViewModel.cs MarcasViewModel.cs

 public class MarcasViewModel : ViewModelBase
    {
        private ObservableCollection<MarcaViewModel> marcas;
        public ObservableCollection<MarcaViewModel> Marcas
        {
            get
            {
                return marcas ;
            }

            set
            {
                marcas  = value;
                RaisePropertyChanged("Marcas");
            }
        }


        public ObservableCollection<MarcaViewModel> GetMarcas()
        {
            marcas = new ObservableCollection<MarcaViewModel>();
            using (var db = new SQLite.SQLiteConnection(App.DBPath))
            {
                var query = db.Table<Marcas>();
                foreach (var _mrc in query)
                {
                    var mrc = new MarcaViewModel()
                    {
                        idMarca  = _mrc.idMarca ,
                        marca  = _mrc.marca                         
                    };
                    marcas.Add(mrc);
                }
            }
            return marcas ;
        }

        public MarcasViewModel()
        {
            this.marcas = GetMarcas();
        }

    }

ViewModelBase.cs ViewModelBase.cs

 public class ViewModelBase
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }

UPDATE1: UPDATE1:

when I select a brand item, only the next code is called and in this order: 当我选择一个品牌商品时,只有下一个代码被调用,并且顺序如下:

1st (in FillinfgForm.cs) 第一个(在FillinfgForm.cs中)

 private void cmbMarca_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {            
                MarcaViewModel curItem = (MarcaViewModel)cmbMarca.SelectedItem;        
                this.cmbMarca.Tag  = curItem.idMarca;            
        }  

2nd (in FillingViewModel.cs) 第二(在FillingViewModel.cs中)

public int SelectedMarca 
  set 
            {
                _selectedMarca = value;
                RaisePropertyChanged("SelectedMarca");
                modelosSAT.MarcaID = _selectedMarca;           
            }

3rd (in ModelosViewModel.cs) 第三 (在ModelosViewModel.cs中)

Public int MarcaID
    {            
        set
        {
            _marcaID = value;
            RaisePropertyChanged("MarcaID");
            this.GetModelos();
        }
    }

4th 第四名

public ObservableCollection<ModeloViewModel> GetModelos()
    {
        modelos  = new ObservableCollection<ModeloViewModel>();
        using (var db = new SQLite.SQLiteConnection(App.DBPath))
        {
            var query = db.Table<Modelos>().Where(c => c.idMarca == _marcaID);   
            //var query = db.Table<Modelos>();   
            foreach (var _mrc in query)
            {
                var mrc = new ModeloViewModel()
                {
                    idMarca  = _mrc.idMarca,
                    idModelo = _mrc.idModelo,
                    modelo   = _mrc.modelo                          
                };
                modelos.Add(mrc);
            }
        }
        return modelos ;
    }

The problem is in GetMarcas() methods. 问题出在GetMarcas()方法中。 As you can see you work not with the property but with the field - 'marcas'. 如您所见,您不使用属性,而是使用“ marcas”字段。 But when you assign a value to a field (in you particular case marcas = new ObservableCollection();) PropertyChanged method is not invoked. 但是,当您为字段分配值时(在特殊情况下,marcas = new ObservableCollection();),不会调用PropertyChanged方法。 That is why you don't see UI changes. 这就是为什么您看不到UI更改的原因。 You should work with the property istead of field or you can clear the existing ObservableCollection and add you values. 您应该使用属性而不是field,或者可以清除现有的ObservableCollection并添加值。 Both variants should work. 两种变体都应该起作用。 So the following code should work: 因此,以下代码应该工作:

public ObservableCollection<MarcaViewModel> GetMarcas()
{
    Marcas = new ObservableCollection<MarcaViewModel>();
    using (var db = new SQLite.SQLiteConnection(App.DBPath))
    {
        var query = db.Table<Marcas>();
        foreach (var _mrc in query)
        {
            var mrc = new MarcaViewModel()
            {
                idMarca  = _mrc.idMarca ,
                marca  = _mrc.marca                         
            };
            marcas.Add(mrc);
        }
    }
    return marcas ;
}

or, a better solution: 或者,更好的解决方案:

public ObservableCollection<MarcaViewModel> GetMarcas()
{
    Marcas.Clear();
    using (var db = new SQLite.SQLiteConnection(App.DBPath))
    {
        var query = db.Table<Marcas>();
        foreach (var _mrc in query)
        {
            var mrc = new MarcaViewModel()
            {
                idMarca  = _mrc.idMarca ,
                marca  = _mrc.marca                         
            };
            Marcas.Add(mrc);
        }
    }
    return marcas;
}

Also there is a good practice called "do not ignore return values", as you can see you don't need to return ObservableCollection from GetMarcas , so either rewrite it so that it returns nothing or rewrite invoking code (it dependes on your existing code). 还有一种称为“不要忽略返回值”的优良作法,如您所见,您不需要从GetMarcas返回ObservableCollection,因此可以重写它以使其不返回任何内容或重写调用代码(这取决于您现有的代码) )。

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

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