虽然BindingList<T>并ObservableCollection<T>提供了检测列表更改的机制,但它们不支持在更改发生之前检测/拦截更改的机制.
我正在写几个接口来支持这个,但我想画出你的意见.
选项1:列表为每种类型的操作引发事件
在这里,消费者可能会编写如下代码:
public class Order : Entity
{
public Order()
{
this.OrderItems = new List<OrderItem>();
this.OrderItems.InsertingItem += new ListChangingEventHandler<OrderItem>(OrderItems_InsertingItem);
this.OrderItems.SettingItem += new ListChangingEventHandler<OrderItem>(OrderItems_SettingItem);
this.OrderItems.RemovingItem += new ListChangingEventHandler<OrderItem>(OrderItems_RemovingItem);
}
virtual public List<OrderItem> OrderItems { get; internal set; }
void OrderItems_InsertingItem(object sender, IOperationEventArgs<OrderItem> e)
{
if (!validationPasses)
{
e.Cancel = true;
return;
}
e.Item.Parent = this;
}
void OrderItems_SettingItem(object sender, IOperationEventArgs<OrderItem> e)
{
if (!validationPasses)
{
e.Cancel = true;
return;
}
e.Item.Parent = this; …Run Code Online (Sandbox Code Playgroud) 我有一个需要添加项目的工作线程BindingList.但是,BindingList数据绑定为a DataGridView.所以,当我尝试添加到列表中时,我得到了一个InvalidOperationException (Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on.)
通常,对于此例外,您可以:
if(winformControl.InvokeRequired) {
winformControl.Invoke(MethodDelegate);
}
Run Code Online (Sandbox Code Playgroud)
然而,数据绑定会使事情变得混乱,因为看不到Winform控件.我只有以下行,它抛出异常:
ClassInstance.MyBindingList.Add(myObject);
Run Code Online (Sandbox Code Playgroud)
如果你有专门针对这种情况的解决方案,那很好.
如果没有,我怎样才能让工作线程告诉我的主线程执行一个特定的方法(工作线程提供了几个参数)?这可能是一个更好的选择,因为我的工作线程实际上正在做一堆东西(比如写入数据库),而且我不确定一切是否是线程安全的.我是一名学生,也是多线程的新手,而且这真的不是我的强项.
我在我的应用程序中有以下代码.但Listchanged事件未按预期触发.我有一个"预订"对象.我是从frmMain打电话给我的.你能告诉我这个问题吗?
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.ComponentModel;
namespace CustomObjects
{
public class Booking:ObjectBase
{
private int pBookingNo=0;
private BindingList<Loans> pCashLoans = new BindingList<Loans>();
public int BookingNo
{
get { return pBookingNo; }
set
{
if (!value.Equals(pBookingNo))
{
pBookingNo = value;
PropertyHasChanged("BookingNo");
}
}
}
public BindingList<Loans> CashLoans
{
get { return pCashLoans; }
set
{
pCashLoans = value;
//CalculateCashLoan(this,new System.ComponentModel.ListChangedEventArgs(ListChangedType.Reset,-1));
PropertyHasChanged("CashLoans");
}
}
private decimal pTakenCashLoan = 0;
public decimal TakenCashLoan
{
get { return pTakenCashLoan; …Run Code Online (Sandbox Code Playgroud) 我想过滤我的DataGridView数据.我的DataGridView的DataSource绑定到了BindingSource.BindingSource包含我clsBillHeader班级中的对象列表.
这是第一段代码:
Dim bSource As New BindingSource
bSource.DataSource = clsBillHeader.GetAll()
dgvBills.DataSource = bSource
bSource.Filter = "JobNumber Like '100%'" //Filter doesn't actually work
Run Code Online (Sandbox Code Playgroud)
得到所有()
Public Shared Function GetAll() As List(Of clsBillHeader)
Dim mycn As New SqlConnection(connection)
Dim mycmd As New SqlCommand("SELECT * FROM Headers", mycn)
mycn.Open()
Dim myreader As SqlDataReader = mycmd.ExecuteReader
Dim myList As New List(Of clsBillHeader)
While myreader.Read
Dim item As New clsBillHeader()
SetByReader(myreader, item) //Sets all values correctly (such as forein keys)
myList.Add(item)
End …Run Code Online (Sandbox Code Playgroud) 我能够获得添加到BindingList的项目索引.当我尝试获取索引时,如果删除的项目我得到错误
Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
Run Code Online (Sandbox Code Playgroud)
这是我的代码
Private Sub cmdRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRemove.Click
For i As Integer = 0 To _assignedSelection.SelectedCount - 1
Dim item As Jurisdiction = CType(_assignedSelection.GetSelectedRow(i), Jurisdiction)
_list.Remove(item)
Next
End Sub
Private Sub list_Change(ByVal sender As Object, ByVal e As ListChangedEventArgs) Handles _list.ListChanged
If (_list.Count > 0) Then
Select Case e.ListChangedType
Case ListChangedType.ItemAdded
_dal.InsertJurisdiction(_list.Item(e.NewIndex))
Case ListChangedType.ItemDeleted
'MsgBox(e.NewIndex.ToString) …Run Code Online (Sandbox Code Playgroud) 将数组转换为BindingList最简单快捷的方法是什么?
我坚持使用BindingList,其中T是扩展A接口的接口.当我在绑定中使用此bindingList时,只有来自T的属性是可见的,而来自继承的A接口的属性则不可见.为什么会这样?它看起来像.net错误.我需要为我的2个项目分享一些常用功能.当PropertyChanged事件通过baseImplementation进行隧道传输时,绑定List的PropertyDescriptor为空.附加的接口和实现.SetUp方法到底
interface IExtendedInterface : IBaseInterface
{
string C { get; }
}
interface IBaseInterface : INotifyPropertyChanged
{
string A { get; }
string B { get; }
}
public class BaseImplementation : IBaseInterface
{
public string A
{
get { return "Base a"; }
}
public string B
{
get { return "base b"; }
protected set
{
B = value;
OnPropertyChanged("B");
}
}
protected void OnPropertyChanged(string p)
{
if (PropertyChanged != null)
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(p));
}
public event System.ComponentModel.PropertyChangedEventHandler …Run Code Online (Sandbox Code Playgroud) 我有一个Asynchronous BindingList,它包含在工作线程上操作并绑定到主UI线程上的BindingSource的对象,其中BindingSource绑定到DataGridView.
有没有可能在我的BindingList中找到对象而不迭代列表?
我看过LINQ的引擎盖,它基本上是一个糖涂层的foreach循环.另外从我的理解,如果我实现IBindingList.Find()它只不过是一个for循环...
我已经"尝试"将我的BindingList同步/映射到一个反映我的BindingList的字典,并使用Dictionary来定位对象并将结果(索引)传递给我的BindingList,但这不起作用,因为添加和删除太多了对象和我无法保持井井有条.
这是一款高性能的应用程序,处理来自股票市场的实时高频数据.这就是为什么我不能遍历BindingList,这太低效了.
有人可以给我一些建议和/或解决方案.
假设,我有对象:
public interface ITest
{
string Data { get; set; }
}
public class Test1 : ITest, INotifyPropertyChanged
{
private string _data;
public string Data
{
get { return _data; }
set
{
if (_data == value) return;
_data = value;
OnPropertyChanged("Data");
}
}
protected void OnPropertyChanged(string propertyName)
{
var h = PropertyChanged;
if (null != h) h(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Run Code Online (Sandbox Code Playgroud)
及其持有人:
private BindingList<ITest> _listTest1;
public BindingList<ITest> ListTest1 { get { return _listTest1 ?? (_listTest1 …Run Code Online (Sandbox Code Playgroud) 我有一个集合视图,我想在其中应用大于平均水平的过滤器。问题是列类型是字符串。因此,正常大于任何数字在转换为双精度类型后都可以完美工作,问题是如何求平均值。我尝试了以下代码:
collectionView.CustomFilter = $"CONVERT({col}, 'System.Double') > AVG([{col}])";
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,它会中断,因为 AVG 无法应用于字符串类型。但是当我试图把
AVG([CONVERT({col}, 'System.Double')])
Run Code Online (Sandbox Code Playgroud)
它不评估转化。
有什么建议可以克服它吗?
bindinglist ×10
c# ×9
vb.net ×2
winforms ×2
data-binding ×1
datagridview ×1
datatable ×1
inherited ×1
interface ×1
wpf ×1