如何使用Linq语句初始化ObservableCollection

本文介绍了两种将LINQ查询结果填充到ObservableCollection的方法:直接构造和扩展方法。第一种方法利用LINQ查询作为ObservableCollection构造函数的参数。第二种方法通过定义一个ForEach扩展方法来迭代LINQ查询结果并添加到集合中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一种方法可以直接使用linq的查询结果做为ObservableCollection构造函数的参数,

	ObservableCollection<Assignment> Assignments = new ObservableCollection<Assignment>(
                			from a in App.LocalDataBase.Assignments
                			where a.CourseName == ApplicationTitle && a.StartDate == date
                			select a
                			);


第二种方式定义一个扩展方法因为 linq查询的结果是返回一个集合类型IQueryable<T>,它实现了IEnumable<T>接口.所以这个扩展方法可以这样写

	static public void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
         {
             foreach (var item in collection)
             {
                 action(item);
             }
         }

用的时候这样

	(from a in App.LocalDataBase.Assignments
          where a.CourseName == ApplicationTitle && a.StartDate == date
          select a).ForEach(Assignments.Add);


 


 

DbContext类: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data.Entity; using VisualGuidance.Model; using System.Reflection.Emit; namespace VisualGuidance.DB { public class DBContext:DbContext { public DBContext() : base("sqliteContext") //sqliteContext为App.Config中配置的连接字符串名称 { } public virtual DbSet<CameraInfo> CameraInfos { get; set; } } } CameraInfo类: using GalaSoft.MvvmLight; using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace VisualGuidance.Model { // CameraInfo.cs [Table("CameraInfos")] public class CameraInfo : ViewModelBase, IDataErrorInfo { private int _id; private string _cameraName; private string _cameraIPAddress; private string _localIPAddress; private string _createTime; public int ID { get => _id; set => Set(ref _id, value); } public string CameraName { get => _cameraName; set => Set(ref _cameraName, value); } public string CameraIPAddress { get => _cameraIPAddress; set => Set(ref _cameraIPAddress, value); } public string LocalIPAddress { get => _localIPAddress; set => Set(ref _localIPAddress, value); } public string CreateTime { get => _createTime; set => Set(ref _createTime, value); } private bool? _isOpen; public bool? IsOpen { get => _isOpen; set => Set(ref _isOpen, value); } // 相机抓图状态 (改为可空bool) private bool? _isGrabbing; public bool? IsGrabbing { get => _isGrabbing; set => Set(ref _isGrabbing, value); } /// <summary> /// 是否选中 /// </summary> private bool? _IsSelected; public bool? IsSelected { get { return _IsSelected; } set { Set(ref _IsSelected, value); } } /// <summary> /// 相机接口类型:USB、GigE /// </summary> private CameraTypeEnum _CameraType; public CameraTypeEnum CameraType { get => _CameraType; set => Set(ref _CameraType, value); } // 新增曝光时间字段(不映射到数据库) private float _exposureTime; // 默认值 [NotMapped] public float ExposureTime { get => _exposureTime; set => Set(ref _exposureTime, value); } //增益 private float _gain; // 默认值 [NotMapped] public float Gain { get => _gain; set => Set(ref _gain, value); } //帧率 private float _ResultingFrameRate; [NotMapped] public float ResultingFrameRate { get => _ResultingFrameRate; set => Set(ref _ResultingFrameRate, value); } //触发模式 private bool _TriggerMode; [NotMapped] public bool TriggerMode { get => _TriggerMode; set { if (_TriggerMode != value) { _TriggerMode = value; RaisePropertyChanged(nameof(TriggerMode)); // 触发命令执行 TriggerModeChanged?.Invoke(this, EventArgs.Empty); } } } // 添加事件用于通知属性变更 public event EventHandler TriggerModeChanged; // 修改构造函数初始化 public CameraInfo() { _isOpen = false; _isGrabbing = false; // 初始化新增字段 _IsSelected = false; // 默认未选中 _CameraType = CameraTypeEnum.GigE; // 设置默认相机类型 } // IDataErrorInfo实现 public string this[string columnName] { get { switch (columnName) { case nameof(CameraName): return string.IsNullOrWhiteSpace(CameraName) ? "相机名称不能为空" : null; case nameof(CameraIPAddress): if (string.IsNullOrWhiteSpace(CameraIPAddress)) return "相机IP地址不能为空"; return IPAddress.TryParse(CameraIPAddress, out _) ? null : "相机IP地址格式错误"; case nameof(LocalIPAddress): if (string.IsNullOrWhiteSpace(LocalIPAddress)) return "本机IP地址不能为空"; return IPAddress.TryParse(LocalIPAddress, out _) ? null : "本机IP地址格式错误"; default: return null; } } } public string Error => null; } public enum CameraTypeEnum { [Description("USB相机")] USB, [Description("GigE相机")] GigE } } CameraConfigViewModel类: using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; using VisualGuidance.View; using VisualGuidance.DB; using VisualGuidance.Model; using Emrys.FlashLog; using System.Windows.Forms; using VM.Core; using System.Runtime.Remoting.Contexts; using System.Windows; using MessageBox = System.Windows.MessageBox; using System.Text.RegularExpressions; using System.ComponentModel; using System.Collections.ObjectModel; using System.Windows.Input; using KeyEventArgs=System.Windows.Input.KeyEventArgs; using TextBox=System.Windows.Controls.TextBox; using System.Net; namespace VisualGuidance.ViewModel { public class CameraConfigViewModel: ViewModelBase { //复制相机信息 public RelayCommand<CameraInfo> CopyCommand => new RelayCommand<CameraInfo>(CopyCamera); public static CameraConfigViewModel _instance = new CameraConfigViewModel(); public static CameraConfigViewModel Instance() { return _instance; } private CameraConfigViewModel() { GetCameraInfo(); } #region 属性 private CameraInfo _CameraInfoConfig; public CameraInfo CameraInfoConfig { get { return _CameraInfoConfig; } set { if(_CameraInfoConfig!=null) _CameraInfoConfig.PropertyChanged -= CameraInfoConfig_PropertyChanged; Set(ref _CameraInfoConfig, value); if(_CameraInfoConfig!=null) _CameraInfoConfig.PropertyChanged += CameraInfoConfig_PropertyChanged; SaveCommand.RaiseCanExecuteChanged();//更新保存按钮状态 } } //相机列表 private ObservableCollection<CameraInfo> _cameraInfosList = new ObservableCollection<CameraInfo>(); private CameraInfo _selectedCameraInfo; // 添加属性变更监听 private void CameraInfoConfig_PropertyChanged(object sender, PropertyChangedEventArgs e) { SaveCommand.RaiseCanExecuteChanged(); } //获取相机IP信息 public List<string> GetCameraIP() { var ipList = new List<string>(); foreach (var cameraInfo in CameraInfosList) { ipList.Add(cameraInfo.CameraIPAddress); } return ipList; } //获取相机名称 public List<string> GetCameraName() { var nameList = new List<string>(); foreach (var cameraInfo in CameraInfosList) { nameList.Add(cameraInfo.CameraName); } return nameList; } public ObservableCollection<CameraInfo> CameraInfosList { get => _cameraInfosList; set => Set(ref _cameraInfosList, value); } public CameraInfo SelectedCameraInfo { get => _selectedCameraInfo; set => Set(ref _selectedCameraInfo, value); } #endregion #region 命令 //更新相机 public RelayCommand<CameraInfo> RowEditEndingCommand => new RelayCommand<CameraInfo>(UpdateCameraInfo); //新增相机 public RelayCommand AddCommand => new RelayCommand(AddCamera); //删除相机 public RelayCommand DeleteCommand => new RelayCommand(DeleteCamera); //保存配置 public RelayCommand<object> _SaveCommand; public RelayCommand<object> SaveCommand { get { return _SaveCommand ?? (_SaveCommand = new RelayCommand<object>( SaveConfig, obj => CanSave() )); } } public RelayCommand UpdateCommand => new RelayCommand(GetCameraInfo); //取消 public RelayCommand<object> CancelCommand=>new RelayCommand<object>(Cancel); #endregion #region 私有方法 private RelayCommand<UIElement> _enterKeyCommand; public RelayCommand<UIElement> EnterKeyCommand { get { return _enterKeyCommand ?? (_enterKeyCommand = new RelayCommand<UIElement>(element => { if (element is TextBox textBox) { // 强制更新数据源 var binding = textBox.GetBindingExpression(TextBox.TextProperty); binding?.UpdateSource(); // 移动焦点(可选) MoveFocusToNext(textBox); } })); } } private static void MoveFocusToNext(UIElement element) { element.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); } //添加验证方法 private bool CanSave() { if(CameraInfoConfig==null) return false; var errorInfo = (IDataErrorInfo)CameraInfoConfig; return string.IsNullOrEmpty(errorInfo[nameof(CameraInfo.CameraName)]) && string.IsNullOrEmpty(errorInfo[nameof(CameraInfo.CameraIPAddress)]) && string.IsNullOrEmpty(errorInfo[nameof(CameraInfo.LocalIPAddress)]); } private void TextBox_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { var textBox=sender as TextBox; var binding = textBox?.GetBindingExpression(TextBox.TextProperty);//获取绑定表达式 binding?.UpdateSource(); //更新绑定源 //将焦点移到下一个控件 TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Next); textBox?.MoveFocus(request); } } //复制相机信息 private void CopyCamera(CameraInfo sourceCamera) { if (sourceCamera == null) { MessageBox.Show("请选择要复制的相机!"); return; } string newName = GenerateUniqueCameraName(sourceCamera.CameraName); CameraInfo newCamera = new CameraInfo { CameraName = newName, CameraIPAddress = sourceCamera.CameraIPAddress, LocalIPAddress = sourceCamera.LocalIPAddress, CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") }; try { using (DBContext db = new DBContext()) { db.CameraInfos.Add(newCamera); db.SaveChanges(); GetCameraInfo(); FlashLogger.Info("复制相机成功!"); } } catch (Exception ex) { MessageBox.Show($"复制失败: {ex.Message}"); } } //生成唯一的相机名称 private string GenerateUniqueCameraName(string originalName) { var match = Regex.Match(originalName, @"^(.*?)(\d+)$"); string baseName; int number; if (match.Success) { baseName = match.Groups[1].Value; number = int.Parse(match.Groups[2].Value); } else { baseName = originalName; number = 0; } int suffix = number + 1; string newName; do { newName = $"{baseName}{suffix}"; suffix++; } while (CameraInfosList.Any(c => c.CameraName == newName)); return newName; } //获取全部相机信息 private void GetCameraInfo() { try { using (var db = new DBContext()) { var data = db.CameraInfos .AsNoTracking() .ToList() .Select(c => new CameraInfo // 手动映射确保处理NULL { ID = c.ID, CameraName = c.CameraName, CameraIPAddress = c.CameraIPAddress, LocalIPAddress = c.LocalIPAddress, CreateTime = c.CreateTime, // 处理可能的NULL值,默认为false IsOpen = c.IsOpen ?? false, IsGrabbing = c.IsGrabbing ?? false, // 安全处理NULL值 IsSelected = c.IsSelected ?? false, // 修复CameraType处理逻辑 CameraType = ParseCameraType(c.CameraType) }) .ToList(); CameraInfosList = new ObservableCollection<CameraInfo>(data); } } catch (Exception ex) { FlashLogger.Error($"加载数据失败:{ex.Message}\n{ex.StackTrace}"); } } // 新增的CameraType解析方法 private CameraTypeEnum ParseCameraType(string cameraTypeValue) { if (string.IsNullOrWhiteSpace(cameraTypeValue)) return CameraTypeEnum.GigE; // 默认值 // 尝试直接解析枚举名称 if (Enum.TryParse(cameraTypeValue, true, out CameraTypeEnum result)) return result; // 尝试解析为数值(如果数据库存储的是数字) if (int.TryParse(cameraTypeValue, out int numericValue) && Enum.IsDefined(typeof(CameraTypeEnum), numericValue)) { return (CameraTypeEnum)numericValue; } return CameraTypeEnum.GigE; // 解析失败时的默认值 } /// <summary> /// 新增相机 /// </summary> private void AddCamera() { CameraCfgView view = new CameraCfgView(this); CameraInfoConfig=new CameraInfo(); view.ShowDialog(); } /// <summary> /// 删除相机 /// </summary> private void DeleteCamera() { //判断是否选择了相机 if (SelectedCameraInfo == null) { MessageBox.Show("请先选择相机!"); return; } // 显示确认删除对话框 MessageBoxResult confirmToDel = MessageBox.Show("确认要删除所选行吗?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question); if (confirmToDel == MessageBoxResult.Yes) { //删除数据库中的相机信息 using (DBContext db = new DBContext()) { CameraInfo cameraToDelete = db.CameraInfos.Find(SelectedCameraInfo.ID); db.CameraInfos.Remove(cameraToDelete); db.SaveChanges(); //移除CameraInfosList中的项 //CameraInfosList.Remove(SelectedCameraInfo); //触发CameraInfosList的通知 //RaisePropertyChanged("CameraInfosList"); GetCameraInfo(); FlashLogger.Info("删除相机配置成功!"); } //刷新相机列表 //GetCameraInfo(); } else { return; } } //更新相机信息 private void UpdateCameraInfo(CameraInfo camera) { if (camera == null) return; var errorInfo = (IDataErrorInfo)camera; var propsToCheck = new[] { nameof(CameraInfo.CameraName), nameof(CameraInfo.CameraIPAddress),nameof(CameraInfo.LocalIPAddress)}; // 检查基础验证错误(如空值) bool hasValidationError = propsToCheck.Any(p => !string.IsNullOrEmpty(errorInfo[p])); // 新增IP地址格式验证 bool invalidCameraIP = !IsValidIPAddress(camera.CameraIPAddress); bool invalidLocalIP = !IsValidIPAddress(camera.LocalIPAddress); if (hasValidationError || invalidCameraIP || invalidLocalIP) { string errorMessage = "存在无效输入:"; if (hasValidationError) errorMessage += "\n- 请检查红色标记字段"; if (invalidCameraIP) errorMessage += $"\n- 相机IP格式无效: {camera.CameraIPAddress}"; if (invalidLocalIP) errorMessage += $"\n- 本机IP格式无效: {camera.LocalIPAddress}"; MessageBox.Show(errorMessage); return; } try { using (var db = new DBContext()) { var existing = db.CameraInfos.Find(camera.ID); if (existing == null) return; existing.CameraName = camera.CameraName; existing.CameraIPAddress = camera.CameraIPAddress; existing.LocalIPAddress = camera.LocalIPAddress; db.SaveChanges(); FlashLogger.Info($"已更新相机配置:{camera.ID}"); } // 刷新本地数据 var index = CameraInfosList.IndexOf(camera); if (index >= 0) { CameraInfosList[index] = camera; } } catch (Exception ex) { MessageBox.Show($"更新失败:{ex.Message}"); FlashLogger.Error($"更新异常:{ex.Message}"); } } private bool IsValidIPAddress(string ip) { if (string.IsNullOrWhiteSpace(ip))//检查一个字符串是否为空、为null或者只包含空格 return false; // 支持IPv4和IPv6格式验证 return IPAddress.TryParse(ip, out IPAddress address) && address.ToString() == ip; // 防止格式规整化 } //保存配置 private void SaveConfig(object obj) { if (!CanSave()) { MessageBox.Show("存在无效输入,请检查红色标记字段"); return; } try { using (DBContext db = new DBContext()) { CameraInfoConfig.CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"); db.CameraInfos.Add(CameraInfoConfig); db.SaveChanges(); GetCameraInfo(); FlashLogger.Info("新增相机配置成功!"); Window win=obj as Window; win.Close(); } }catch (Exception ex) { MessageBox.Show("错误:"+ex.Message); } } //取消 private void Cancel(object obj) { Window win = obj as Window; win.Close(); } #endregion } } 现在帮我实现GetCameraInfo这个方法,修改代码实现功能;
最新发布
06-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值