gpt4 book ai didi

c# - ObservableCollection CollectionChanged 更新数据网格

转载 作者:行者123 更新时间:2023-11-30 14:46:35 24 4
gpt4 key购买 nike

我有一个 DataGrid,它绑定(bind)到一个 ObservableCollection。我有一个动态数据列表,因此可以从列表中编辑/添加/删除项目。起初,我清除并添加了 ObservableCollection 但后来我发现我可以刷新 ObservableCollection 并且我需要为此实现 CollectionChanged但我不确定如果任何机构可以提供一些很棒的指示或示例代码,那将如何。

    private List<OrderList> m_OrderListData = new List<OrderList>();
public List<OrderList> OrderListData
{
get => m_OrderListData;
private set => Set(ref m_OrderListData, value);
}

private ObservableCollection<OrderList> m_OrderListDataCollection;
public ObservableCollection<OrderList> OrderListDataCollection
{
get => m_OrderListDataCollection;
private set => Set(ref m_OrderListDataCollection, value);
}

...
...

m_OrderListDataCollection = new ObservableCollection<OrderList>(m_OrderListData as List<OrderList>);

...
...


foreach (OrderListViewModel Order in OrderList)
{
OrderListData.Add(new OrderList(Order.Description, Order.OrderId));
}

这是我之前的

OrderListData.Clear();
foreach (OrderListViewModel Order in OrderList)
{
OrderListData.Add(new OrderList(Order.Description, Order.OrderId));
}
m_OrderListDataCollection.Clear();
OrderListData.ToList().ForEach(m_OrderListDataCollection.Add);

XAML

                <Label Content="OrderList"/>
<DataGrid Name="dgOrderList"
AutoGenerateColumns="False"
ItemsSource="{Binding Path=OrderListDataCollection}"
IsReadOnly="True"
SelectionMode="Single"
SelectionUnit="FullRow">
<DataGrid.Columns>
<DataGridTextColumn Width="Auto" Header="ID" Binding="{Binding OrderId}"/>
<DataGridTextColumn Width="*" Header="Description" Binding="{Binding OrderDescription}"/>
</DataGrid.Columns>
</DataGrid>

编辑:订单列表类

public class OrderList : INotifyPropertyChanged
{

private string m_OrderDescription;
private string m_OrderId;

public string OrderDescription
{
get => m_OrderDescription;
set => Set(ref m_OrderDescription, value);
}

public string OrderId
{
get => m_OrderId;
set => Set(ref m_OrderId, value);
}

#region Constructor
public OrderList()
{
}
public OrderList(string description, string id)
{
m_OrderDescription = description;
m_OrderId = id;
}
#endregion

#region INotifyPropertyChanged

/// <summary>Updates the property and raises the changed event, but only if the new value does not equal the old value. </summary>
/// <param name="PropName">The property name as lambda. </param>
/// <param name="OldVal">A reference to the backing field of the property. </param>
/// <param name="NewVal">The new value. </param>
/// <returns>True if the property has changed. </returns>
public bool Set<U>(ref U OldVal, U NewVal, [CallerMemberName] string PropName = null)
{
VerifyPropertyName(PropName);
return Set(PropName, ref OldVal, NewVal);
}

/// <summary>Updates the property and raises the changed event, but only if the new value does not equal the old value. </summary>
/// <param name="PropName">The property name as lambda. </param>
/// <param name="OldVal">A reference to the backing field of the property. </param>
/// <param name="NewVal">The new value. </param>
/// <returns>True if the property has changed. </returns>
public virtual bool Set<U>(string PropName, ref U OldVal, U NewVal)
{
if (Equals(OldVal, NewVal))
{
return false;
}

OldVal = NewVal;
RaisePropertyChanged(new PropertyChangedEventArgs(PropName));
return true;
}

/// <summary>Raises the property changed event. </summary>
/// <param name="e">The arguments. </param>
protected virtual void RaisePropertyChanged(PropertyChangedEventArgs e)
{
var Copy = PropertyChanged;
Copy?.Invoke(this, e);
}

/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;

/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG")]
[DebuggerStepThrough]
protected virtual void VerifyPropertyName(string PropertyName)
{
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[PropertyName] == null)
{
string ErrorMsg = "Invalid Property Name: " + PropertyName + "!";

if (ThrowOnInvalidPropertyName)
{
throw new Exception(ErrorMsg);
}

Debug.Fail(ErrorMsg);
}
}

/// <summary>
/// Returns whether an exception is thrown, or if a Debug.Fail() is used
/// when an invalid property name is passed to the VerifyPropertyName method.
/// The default value is false, but subclasses used by unit tests might
/// override this property's getter to return true.
/// </summary>
protected virtual bool ThrowOnInvalidPropertyName { get; } = true;

最佳答案

如果您只是将 ObservableCollection 绑定(bind)到 DataGridSource,那么它应该会按预期工作。
当添加新项目或删除项目时,您的 View 将收到更新其数据的通知。

要跟踪实际更改,您不需要需要实现列表的 CollectionChanged 事件,但您必须使列表中的实际对象可观察。要使对象可观察,您必须实现 INotifyPropertyChanged 接口(interface)。
一旦对象是可观察的,并且一个属性发出一个 PropertyChanged 通知,可观察集合将捕捉到它。

这里有一些快速示例代码可以帮助您入门:

1。为可观察对象制作自己的实现

public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged([CallerMemberName] string propName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propName));
}
}

protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value)) return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
}

2。让您的实际对象类扩展此实现,并确保必要的属性发出 PropertyChanged 通知

public class Order : ObservableObject 
{
private long _orderId;
public long OrderId
{
get { return _orderId; }
set { SetProperty(ref _orderId, value); }
}

private string _description;
public string Description
{
get { return _description; }
set { SetProperty(ref _description, value); }
}
}

3。确保你的 ViewModel 有一个 ObservableCollection

(ViewModel 也应该是可观察的。我希望您已经是这种情况,否则 MVVM 将很难工作。)

public class MyViewModel : ObservableObject 
{

public MyViewModel()
{
//this is just an example of some test data:
var myData = new List<Order> {
new Order { OrderId = 1, Description = "Test1"},
new Order { OrderId = 2, Description = "Test2"},
new Order { OrderId = 3, Description = "Test3"}
};
//Now add the data to the collection:
OrderList = new ObservableCollection<Order>(myData);

}
private ObservableCollection<Order> _orderList;
public ObservableCollection<Order> OrderList
{
get { return _orderList; }
set { SetProperty(ref _orderList, value); }
}
}

4。将 DataGrid 的源绑定(bind)到 ObservableCollection

<DataGrid Name="dgOrderList" 
AutoGenerateColumns="False"
ItemsSource="{Binding OrderList, Mode=TwoWay}"
IsReadOnly="True"
SelectionMode="Single"
SelectionUnit="FullRow">
<DataGrid.Columns>
<DataGridTextColumn Width="Auto" Header="ID" Binding="{Binding OrderId}"/>
<DataGridTextColumn Width="*" Header="Description" Binding="{Binding OrderDescription}"/>
</DataGrid.Columns>
</DataGrid>

关于c# - ObservableCollection CollectionChanged 更新数据网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48464498/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com