我如何通知容器对象一个 属性 已经从正在更改的对象更改?
How do I notify the container object that a property has changed from the object being changed?
背景:本质上,我正在使用自定义 Android 渲染器在 Xamarin.Forms 中制作网格系统,因为内置的网格实现对于什么来说太慢了我们正在尝试这样做(它无法处理我们需要的同时滚动的 100,000 个单元格)。我已经通过过度耦合成功地做到了这一点,现在我正在按照我的主管要求的方式进行重构,我 运行 遇到了问题。
场景:
//In Xamarin.Forms project
class GridItems : BindableObject {
//Handles/contains all logic to how this grid will be laid out and its children
}
//In Xamarin.Forms project
class Grid : View {
GridItems Source { get; set; }
}
//In Xamarin.Android project
class GridRenderer {
OnElementPropertyChanged() {
//Here I can check what properties inside Grid changed
}
}
这显然非常简单,但是这样设置的原因是您可以简单地子类化 GridItems 来修改网格接受的项目类型,cell/column 的字符串值应该是什么等并重用 Grid 和 GridRenderer 类.
问题:
当 GridItems 在自身内部被修改时,我需要 Grid.GridItems 得到通知。 GridItems 可以引发它的 属性 changed 事件,但是它只会针对本地属性触发。我本质上需要 GridItems 能够告诉 Grid "I have changed, raise YOUR GridItems property changed event",这样 GridRenderer 就可以看到 GridItems 已经改变(因为 Grid 改变了)并且使自己失效,在屏幕上重绘。
有没有一种好方法可以通知包含对象 属性 已从 属性 本身更改?还是我完全错误地解决了这个问题?
所以我设法找到了一种可行的方法来做到这一点,但它可能不适用于大多数未来的人,因为它非常适合我的场景。
本质上,Grid 和 GridItems 都共享一个 ViewModel(页面 ViewModel)。这意味着当 GridItems 的绑定被修改时,ViewModel 可以简单地通过绑定通知 Grid,所以它更像是 ViewModel 在负责。
我在 Grid 中创建了一个可绑定的布尔值,名为 "Invalidate"。每当 ViewModel 修改 GridItems 的子绑定时,它都会通过将 Invalidate 绑定设置为 true 来修改它。
现在在自定义渲染器上,每当为 Grid 触发 ElementPropertyChange 时,它都会检查 Invalidate 是否被触发并且 Invalidate 现在设置为 true。在这种情况下,它只是简单地将元素中的 Invalidate 重置为 false,然后对自身调用 Invalidate(强制 Draw 事件在可能的情况下重新触发并重新加载屏幕)。
背景:本质上,我正在使用自定义 Android 渲染器在 Xamarin.Forms 中制作网格系统,因为内置的网格实现对于什么来说太慢了我们正在尝试这样做(它无法处理我们需要的同时滚动的 100,000 个单元格)。我已经通过过度耦合成功地做到了这一点,现在我正在按照我的主管要求的方式进行重构,我 运行 遇到了问题。
场景:
//In Xamarin.Forms project
class GridItems : BindableObject {
//Handles/contains all logic to how this grid will be laid out and its children
}
//In Xamarin.Forms project
class Grid : View {
GridItems Source { get; set; }
}
//In Xamarin.Android project
class GridRenderer {
OnElementPropertyChanged() {
//Here I can check what properties inside Grid changed
}
}
这显然非常简单,但是这样设置的原因是您可以简单地子类化 GridItems 来修改网格接受的项目类型,cell/column 的字符串值应该是什么等并重用 Grid 和 GridRenderer 类.
问题:
当 GridItems 在自身内部被修改时,我需要 Grid.GridItems 得到通知。 GridItems 可以引发它的 属性 changed 事件,但是它只会针对本地属性触发。我本质上需要 GridItems 能够告诉 Grid "I have changed, raise YOUR GridItems property changed event",这样 GridRenderer 就可以看到 GridItems 已经改变(因为 Grid 改变了)并且使自己失效,在屏幕上重绘。
有没有一种好方法可以通知包含对象 属性 已从 属性 本身更改?还是我完全错误地解决了这个问题?
所以我设法找到了一种可行的方法来做到这一点,但它可能不适用于大多数未来的人,因为它非常适合我的场景。
本质上,Grid 和 GridItems 都共享一个 ViewModel(页面 ViewModel)。这意味着当 GridItems 的绑定被修改时,ViewModel 可以简单地通过绑定通知 Grid,所以它更像是 ViewModel 在负责。
我在 Grid 中创建了一个可绑定的布尔值,名为 "Invalidate"。每当 ViewModel 修改 GridItems 的子绑定时,它都会通过将 Invalidate 绑定设置为 true 来修改它。
现在在自定义渲染器上,每当为 Grid 触发 ElementPropertyChange 时,它都会检查 Invalidate 是否被触发并且 Invalidate 现在设置为 true。在这种情况下,它只是简单地将元素中的 Invalidate 重置为 false,然后对自身调用 Invalidate(强制 Draw 事件在可能的情况下重新触发并重新加载屏幕)。