gpt4 book ai didi

wpf - 没有数据绑定(bind)时将属性从模型传递到 View

转载 作者:行者123 更新时间:2023-12-03 10:16:16 26 4
gpt4 key购买 nike

我知道这已经被讨论了很多,但我无法让它发挥作用。

我在 WPF 中有一个 View - ViewModel - 模型。
我需要传递模型中的属性已更改的信息。我需要最终在 View 中处理信息。
注意有没有数据绑定(bind)这里从 View 到 ViewModel。

在 ViewModel 我有一组模型对象:

Public Property Items as ObservableCollection(Of Item)

模型是:
Public Class Item
Public Property Name as String
End Class

我想要做的是在 ViewModel 中的集合“Items”中的任何项目中更改属性“Name”时运行的 View 代码隐藏(见下文)中运行一个过程。

看法:
Private Sub NameWasChanged()
'do something to UI...
'Item that was changed must be known here as must the new value for the "Name" property
End Sub

更新 1 >>>

为了响应您的自定义类,我尝试将其转换为 VB.NET(如下),但看起来在此派生类中覆盖事件存在一些问题。不知道“ protected 阴影事件 PropertyChanged”是否是正确的方法。我得到 item.PropertyChanged 说“PropertyChanged 不是 T 事件”。
你能帮我解决这个问题吗?否则我得到了这个概念/想法。
Public Class BaseCollection(Of T)

Inherits ObservableCollection(Of T)
Implements INotifyPropertyChanged

Protected currentItem As T

Public Sub New(collection As IEnumerable(Of T))
Me.New()
For Each item As T In collection
Add(item)
Next
End Sub

Public Sub New(collection As ObservableCollection(Of T))
Me.New(TryCast(collection, IEnumerable(Of T)))
End Sub

Public Sub New(ParamArray collection As T())
Me.New(TryCast(collection, IEnumerable(Of T)))
End Sub

Public Sub New()
MyBase.New()
End Sub


Public Shadows Sub Add(item As T)
AddHandler item.PropertyChanged, AddressOf Item_PropertyChanged
MyBase.Add(item)
End Sub

Public Overridable Shadows Sub Add(collection As IEnumerable(Of T))
For Each item As T In collection
Add(item)
Next
End Sub

Public Overridable Shadows Sub Add(ParamArray items As T())
Add(TryCast(items, IEnumerable(Of T)))
End Sub

Protected Overrides Sub InsertItem(index As Integer, item As T)
If item IsNot Nothing Then
AddHandler item.PropertyChanged, AddressOf Item_PropertyChanged
MyBase.InsertItem(index, item)
End If
End Sub

Protected Overrides Sub ClearItems()
For Each item As T In Me
RemoveHandler item.PropertyChanged, AddressOf Item_PropertyChanged
Next
MyBase.ClearItems()
End Sub

Public Shadows Function Remove(item As T) As Boolean
If item Is Nothing Then
Return False
End If
RemoveHandler item.PropertyChanged, AddressOf Item_PropertyChanged
Return MyBase.Remove(item)
End Function

Public Shadows Sub RemoveAt(index As Integer)
Dim item As T = Me(index)
If item IsNot Nothing Then
RemoveHandler item.PropertyChanged, AddressOf Item_PropertyChanged
End If
MyBase.RemoveAt(index)
End Sub


Private Sub Item_PropertyChanged(sender As Object, e As PropertyChangedEventArgs)
NotifyPropertyChanged(e.PropertyName)
End Sub


#Region "INotifyPropertyChanged Members"

Protected Shadows Event PropertyChanged As PropertyChangedEventHandler

Protected Overridable Sub NotifyPropertyChanged(ParamArray propertyNames As String())
For Each propertyName As String In propertyNames
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
Next
End Sub

#End Region


End Class

最佳答案

如果模型类正确实现 INotifyPropertyChanged接口(interface),另一个类可以通过将处理程序附加到 INotifyPropertyChanged.PropertyChanged 来监听属性更改。事件:

YourObject.PropertyChanged += YourObject_PropertyChanged;

...


Private Sub YourObject_PropertyChanged(sender As Object, e As PropertyChangedEventArgs)
If InlineAssignHelper(e.PropertyName, "Name") Then
' Do something with the new Name value here
End If
End Sub

更新>>>

如果你想监控你的 Items中每一项的属性变化集合属性,那么您需要将处理程序附加到每个项目...您可以执行以下操作:
For Each item As Item In Items
item.Propertychanged += Item_PropertyChanged
Next

或者当您将它们添加到 Items 时:
For Each item As Item In OtherCollection
item.Propertychanged += Item_PropertyChanged
Items.Add(item)
Next

当我需要这样做时,我扩展 ObservableCollection<T>类并覆盖 Add附加处理程序的方法(并从构造函数中调用它们)并覆盖 Remove删除处理程序的方法。

更新 2 >>>

我的扩展 ObservableCollection<T>类(class)太长了,无法在这里展示,但首先要让你开始,这里有一些......我只是希望我没有删除太多,它仍然有效......无论如何,我想你会明白了:
public class BaseCollection<T> : ObservableCollection<T>, INotifyPropertyChanged 
where T : class, INotifyPropertyChanged
{
public BaseCollection(IEnumerable<T> collection) : this()
{
foreach (T item in collection) Add(item);
}

public BaseCollection(ObservableCollection<T> collection) : this(collection as IEnumerable<T>) { }

public BaseCollection(params T[] collection) : this(collection as IEnumerable<T>) { }

public BaseCollection() : base() { }

public new void Add(T item)
{
item.PropertyChanged += Item_PropertyChanged;
base.Add(item);
}

public virtual void Add(IEnumerable<T> collection)
{
foreach (T item in collection) Add(item);
}

public virtual void Add(params T[] items)
{
Add(items as IEnumerable<T>);
}

protected override void InsertItem(int index, T item)
{
if (item != null)
{
item.PropertyChanged += Item_PropertyChanged;
base.InsertItem(index, item);
}
}

protected override void ClearItems()
{
foreach (T item in this) item.PropertyChanged -= Item_PropertyChanged;
base.ClearItems();
}

public new bool Remove(T item)
{
if (item == null) return false;
item.PropertyChanged -= Item_PropertyChanged;
return base.Remove(item);
}

public new void RemoveAt(int index)
{
T item = this[index];
if (item != null) item.PropertyChanged -= Item_PropertyChanged;
base.RemoveAt(index);
}

private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
NotifyPropertyChanged(e.PropertyName);
}

#region INotifyPropertyChanged Members

protected override event PropertyChangedEventHandler PropertyChanged;

protected virtual void NotifyPropertyChanged(params string[] propertyNames)
{
if (PropertyChanged != null)
{
foreach (string propertyName in propertyNames) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

#endregion
}

}

有了这个,你可以添加一个 PropertyChanged集合的处理程序:
BaseCollection<YourDataType> items = new BaseCollection<YourDataType>();
items.PropertyChanged += Item_PropertyChanged;

关于wpf - 没有数据绑定(bind)时将属性从模型传递到 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19492116/

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