【问题标题】:Update combobox MVVM (XAML & C#)更新组合框 MVVM(XAML 和 C#)
【发布时间】:2015-03-21 18:45:32
【问题描述】:

我有一个包含 2 个组合的表单,以及其他字段。 1 个组合中包含品牌名称 (cmbMarca)。此组合已正确填充。 另一个组合 (cmbModelo) 应填写所选品牌的型号。

我的问题是在选择品牌 (cmbrand) 时没有更新与模型 (cmbModelo) 的组合。当我选择一个品牌时,运行所有代码但不显示组合“cmbModelo”中的任何项目

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

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

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

 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

 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

 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));
            }
        }

    }

更新1:

当我选择一个品牌项目时,只调用下一个代码并按此顺序:

第一个(在 FillinfgForm.cs 中)

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

第二个(在 FillingViewModel.cs 中)

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

第 3 个(在 ModelosViewModel.cs 中)

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

第四次

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 ;
    }

【问题讨论】:

  • 你使用调试器了吗? Setter 和 gettr 中的断点?什么叫?什么不叫?
  • @DrKoch 更新了我的问题。
  • 不要在构造函数和/或你的属性中调用冗长的操作,它会阻塞你的 UI 线程。使用异步命令启动冗长操作或导航感知视图模型(如在 Prims 中实现)来处理冗长操作
  • @tseng 感谢您的评论。我会解决的。

标签: c# xaml mvvm combobox


【解决方案1】:

问题出在GetMarcas() 方法中。 如您所见,您不是在物业上工作,而是在田野上工作-“马卡斯”。但是,当您为字段分配值时(在您的特定情况下,marcas = new ObservableCollection();)不会调用 PropertyChanged 方法。这就是为什么您看不到 UI 更改的原因。 您应该使用属性而不是字段,或者您可以清除现有的 ObservableCollection 并添加您的值。两种变体都应该起作用。 所以下面的代码应该可以工作:

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 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;
}

还有一个叫做“不要忽略返回值”的好习惯,你可以看到你不需要从GetMarcas返回 ObservableCollection,所以要么重写它以使其不返回任何内容,要么重写调用代码(它取决于您现有的代码)。

【讨论】:

  • 但是 GetMarcas() (Brands) 运行良好。组合“cmbMarcas”已正确填充。问题出在组合中:cmbModel (Modelos)。我已经更新了我的问题。
  • 对于模型也一样,而不是 modelos = new ObservableCollection&lt;ModeloViewModel&gt;(); 尝试写 Modelos.Clear()
  • Alex:我试过了,但后来我收到了这个错误:nameapp.exe 中发生了“System.NullReferenceException”类型的异常,但未在用户代码中处理。 {"对象引用未设置为对象的实例。"}
  • 如果我尝试您的第一个解决方案,请设置 { modelos = value; RaisePropertyChanged("Modelos"); } 被调用,但组合“cmbModelo”中没有显示任何项目
  • 尝试将private ObservableCollection&lt;ModeloViewModel&gt; modelos; 更改为private ObservableCollection&lt;ModeloViewModel&gt; modelos = new ObservableCollecion&lt;ModeloViewModel&gt;(); 并使用modelos.Clear()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 2015-12-17
  • 2018-06-12
  • 1970-01-01
  • 2021-09-16
  • 2015-04-27
  • 1970-01-01
相关资源
最近更新 更多